Written Information Security Plan (WISP)
Andivano LLC — Taxller
| Effective date | 2026-10-26 |
| Version | 1.19 |
| Approved by | Managing Member, Andivano LLC |
| Security / support contact | info@taxller.com |
1. Purpose & Scope
This Written Information Security Plan ("WISP") describes the administrative, technical, and physical safeguards that Andivano LLC, a Florida single-member LLC operating the product Taxller (https://taxller.com), applies to protect the information it collects, processes, and stores.
Taxller is a cloud bookkeeping and tax-compliance SaaS built for US-based Amazon sellers. Taxller has been live in early access since August 13, 2026, and production holds real customer account data and seller-uploaded documents.
On September 8, 2026 the production environment was migrated off Amazon Web Services onto a dedicated single-tenant Linux server operated by Andivano LLC (the "production server", located in the United States). The application and its PostgreSQL database now run on that server behind a TLS-terminating reverse proxy; they no longer run on AWS container or managed-database services. Two AWS services remain in use and remain in scope: encrypted S3 object storage for customer documents and assistant attachments, and Amazon Bedrock (US regions only) for the product's AI assistant. The same account also holds, in a bucket of its own, the encrypted report archive of the private integration described in Section 7a.
Paid subscriptions have been available since August 22, 2026. Billing is processed by Stripe; card data is handled entirely inside Stripe's PCI DSS-compliant environment and never reaches Taxller systems (Section 12).
This WISP describes (a) the security controls operating in production today, and (b) the specific, dated commitments Andivano LLC is making for controls that mature at defined trigger points, rather than claiming those controls are already operating.
This WISP applies to:
-
The Taxller production server: the application, its PostgreSQL database, the reverse proxy, the release mechanism, and the backup chain.
-
The AWS services the product still depends on — the S3 document store and Amazon Bedrock — held in an AWS account dedicated to Taxller (
us-east-1); Section 7a records one exception. -
The Taxller product repository (source code, CI/CD, dependency management).
-
The Taxller marketing site (taxller.com, hosted on Hostinger, static export — a separate, non-application surface with no access to product data).
-
Andivano LLC's Amazon Selling Partner API (SP-API) presence, which is deliberately split into two separate Solution Provider Portal accounts so that the product and the company's own trading never share one review surface or one set of SP-API credentials:
- The Taxller application (the subject of this WISP). Andivano LLC is registering a second Solution Provider Portal account, held by the same legal entity under its own login, as a Public developer so that other selling partners can authorize this application. That account requests exactly four non-restricted roles — Finance and Accounting, Inventory and Order Tracking, Amazon Fulfillment, and Selling Partner Insights — to be exercised on behalf of Taxller's seller customers, each under that seller's own OAuth authorization. Until the registration is approved, no third-party seller has authorized the application.
- A pre-existing private integration, predating the Taxller application, on Andivano LLC's original developer profile. That profile stays Private and unchanged. It holds seven approved non-restricted roles — the four above plus Product Listing, Pricing, and Brand Analytics — used exclusively for Andivano LLC's own Amazon seller account under self-authorization, and never exercised on behalf of a third-party selling partner. It is out of scope for the Taxller application except where this plan says otherwise (Section 7a).
Every role held or requested in either account is non-restricted; no restricted role, and no role that grants access to Amazon buyer personal data, is held or requested anywhere.
-
The internal automation environment behind Andivano LLC's private SP-API integration described above — a hardened Linux host, documented in Section 7a.
Where this document states an infrastructure control in the present tense, that statement is attested by
dated evidence kept alongside this document: the output of the AWS baseline verification script
(infra/aws-baseline/verify.sh, or its read-only boto3 equivalent infra/aws-baseline/verify.py, which
checks the same controls from a workstation) for the AWS services in scope, the output of
infra/ops-host/spapi-archive/archive.py verify for the report-archive bucket of Section 7a, and the production server's own acceptance
record — firewall rules, externally reachable ports, service inventory, and a verified backup restore —
captured at the September 8, 2026 migration and re-captured whenever that host's configuration changes.
The plan is not submitted to any third party before that evidence is refreshed.
This document is published in the product repository and mirrored on the public /security page. It is
reviewed at least annually per Section 14, and companion to the separate Incident Response Runbook
(same repository; its current version and effective date are given in Section 13), which governs
operational incident-handling procedures.
2. Roles & Responsibilities
Andivano LLC is a single-member LLC. As of this document's effective date there are no employees or contractors with access to Taxller infrastructure or data.
| Role | Assigned to | Responsibilities |
|---|---|---|
| Security Officer / Data Protection Owner | Managing Member, Andivano LLC | Owns this WISP and the Incident Response Runbook; approves all changes to security policy; sole holder of AWS root credentials; final authority on access grants. |
| Incident Commander | Managing Member, Andivano LLC | Leads incident detection, containment, and notification per Section 13 and the Incident Response Runbook, until a dedicated hire assumes the role. |
| Administrator (AWS, GitHub, SP-API app) | Managing Member, Andivano LLC | Day-to-day administration of the production server, the dedicated AWS account, the product repository, and the SP-API developer application. |
Commitment — trigger: first additional hire or contractor with system access. Before any person other than the Managing Member is granted access to Taxller infrastructure, source code, or seller data, that individual will be assigned a named account (no shared/generic logins), scoped to least privilege for their function, and added to the quarterly access review described in Section 4.
3. Data Classification
Taxller's zero-buyer-PII design is a direct consequence of the SP-API roles it requests: Finance and Accounting, Inventory and Order Tracking, Amazon Fulfillment, and Selling Partner Insights are all classified by Amazon as non-restricted — none of them return Amazon buyer names, addresses, emails, or other buyer-identifying data. Taxller does not request, and by its application scope cannot receive, Amazon buyer PII.
| Category | Examples | Classification | Source |
|---|---|---|---|
| Amazon buyer PII | Buyer name, address, email, phone | Not collected | Excluded by design — none of the non-restricted SP-API roles held or requested by Andivano LLC (the four requested by the Taxller application's account and the seven approved on the private profile, Section 1) return buyer PII |
| Amazon seller operational data | Financial/settlement reports, order and inventory data, fulfillment data, Selling Partner Insights | Confidential | Retrieved from SP-API under the seller's own OAuth authorization |
| Taxller customer account data | Seller's business name, contact email, tax ID (EIN/SSN where applicable for tax-compliance features), billing/subscription status | Confidential / Restricted (tax ID) | Collected directly from the Taxller customer at signup |
| Customer bank data | Bank accounts (names, last four digits, balances), bank transactions with descriptions, counterparties and categories, import results, rules, and the history of actions | Confidential | Statement files the customer uploads and, where offered and authorized by the customer, Plaid, Mercury, and Wise |
| eBay connection data | Fingerprint of the seller's eBay user ID, key identifier, encrypted refresh token and its expiry, connection status and dates; no eBay orders or buyer data | Confidential | eBay, under the seller's own OAuth authorization, where the eBay connection is offered |
| Payment & billing data | Subscription and wallet status, invoices, payment-method metadata (card brand and last four digits) | Confidential | Created by Stripe. Card numbers, CVC, and full payment credentials never transit or rest on Taxller systems (Section 12) |
| Credentials & secrets | LWA client ID/secret, LWA refresh tokens, AWS/IAM credentials, API keys, bank API keys, Plaid access tokens, and eBay refresh tokens | Restricted | Issued by Amazon, AWS, Stripe, Plaid, eBay, and the customer's bank |
| Public content | Marketing site copy, blog, public documentation (incl. this WISP) | Public | Authored by Andivano LLC |
The Amazon seller's own operational data (financial, inventory, order, and fulfillment data returned by SP-API) and the Taxller customer's own account/tax data are treated as Confidential and protected under the same controls described in Sections 4–7, even though neither category constitutes Amazon buyer PII.
4. Access Control
- Production server. Administrative access is by SSH public key only — password authentication is
disabled at the SSH daemon — and the SSH service is reachable only over Andivano LLC's private overlay
network, never from the public internet. The host firewall's default inbound policy is deny. Only named
operating-system accounts may log in (
AllowUsers),MaxAuthTriesis 3, and a failed-authentication jail bans a source address for one hour. The application runs under its own unprivileged account, and the configuration file holding its secrets is mode 600, owned by that account. - Dedicated AWS account. The AWS services Taxller still uses — the S3 document store and Amazon
Bedrock — live in an AWS account created for Taxller, separate from any Amazon seller account, region
us-east-1; Section 7a records one exception. The production server reaches them through a dedicated IAM user scoped to that account's own object prefixes and to the two pinned Bedrock models, and to nothing else. - Root user: MFA-enabled; no root access keys exist or will be created; root is not used for day-to-day administration.
- IAM: named, individual users/roles — no shared or generic logins. Console sign-in requires MFA using an approved factor (hardware-backed passkey/FIDO2, TOTP authenticator app). Programmatic access with access keys is not protected by MFA: the administrative IAM user also has long-lived access keys, held on the host described in Section 7a and used there by administration scripts and by the hourly archive job (Section 7a states the resulting limit and a commitment), and the production server's own IAM user is key-only and narrowly scoped (see the AWS account bullet above). A single named administrative IAM user exists for standing up and operating the account baseline; it will be decomposed into narrower, function-scoped roles (e.g., deploy, read-only audit) as additional infrastructure and any additional personnel are introduced.
- Password policy: IAM account password policy requires a minimum of 14 characters with mixed-case letters, numbers, and special characters; passwords expire after 90 days and the last 24 cannot be reused — exceeding Amazon's 12-character minimum and 365-day expiration baseline.
- Taxller account passwords (the selling partners who sign in to the product): a minimum of 12 characters with uppercase, lowercase, digit and special-character classes all required; candidates are rejected if they appear in a known-breach corpus (k-anonymity lookup, the password never leaves the server); the last 10 passwords cannot be reused; a password older than 365 days forces a change at the next sign-in. The minimum was raised from 8 to 12 on 2026-09-12 to meet Amazon's baseline, and the running product, this plan and the developer-profile questionnaire now state the same policy.
- Multi-factor authentication for Taxller accounts. TOTP multi-factor authentication is optional
for general dashboard access (an owner decision of 2026-08-16) and is enforced where the risk sits: an
account that has enrolled an authenticator must verify it on every new session; a password sign-in on
an account without one is confirmed by a single-use code e-mailed to the verified address; and
starting an Amazon authorization — the only path by which SP-API data reaches Taxller — is refused
unless the user has an enrolled authenticator verified within the preceding five minutes, and the
authorization must then complete within ten minutes. The same fresh verification is required to
connect any marketplace channel, invite a member, disable multi-factor authentication, open Plaid Link
to connect or update a bank, preview or create a Mercury or Wise connection, reconnect a bank,
confirm its accounts, disconnect or delete a bank connection or its data, or sync a Mercury or Wise
connection on demand. The Amazon authorization rule applies when an Amazon authorization starts; it
does not keep an authenticator on the account afterwards. A user may later turn multi-factor
authentication off, after the same fresh verification, and doing so does not revoke an Amazon
authorization the account already holds. Support resets a lost
authenticator only under a documented procedure (
docs/MFA-RESET.md): the user's identity is checked, at least 24 hours pass between the user's confirmation and the reset, the Managing Member approves both the first e-mail to the user and the reset itself, and an active Amazon authorization on the account stops the procedure until the Managing Member decides. Multi-factor authentication remains optional for a dashboard account that has connected nothing. Sign-in to the AWS console and to the source repository requires multi-factor authentication. The production server is reached by SSH public key only, over the private overlay network (Section 7). Programmatic and key-based access, including the access keys described in the IAM bullet above and SSH keys, is not protected by multi-factor authentication. No shared or generic logins exist. - Account lockout — in place. Taxller's authentication layer locks an account for one hour after 10 consecutive failed sign-in attempts, meeting Amazon's "10 or fewer" baseline. The control escalates before it locks: a CAPTCHA challenge is required from the second consecutive failure and an increasing server-side delay from the third; the failure counter decays after 15 minutes without a further attempt; and the account holder can unlock immediately through a single-use emailed link. The counter lives in the application's database, so the limit is per account and survives a restart. This fulfils the commitment made in version 1.0 of this plan, whose trigger — the first customer-facing login — was reached on August 13, 2026.
- Access reviews. Access is currently limited to one individual (the Managing Member); a quarterly
review of all personnel and service-account access is instituted as of this document's effective date,
with the first review due no later than 2026-11-04 and every quarter thereafter, regardless of headcount.
The first review was completed on 2026-10-23 (
evidence/2026-10-23-quarterly-access-review.md); the next review is due no later than 2027-01-23. - Termination. Access for any departing employee, contractor, or service integration is revoked within 24 hours of termination or end of engagement.
5. Encryption
In transit. All data in transit to and from Taxller systems — including calls to the Amazon SP-API — uses TLS 1.2 or higher; weaker protocols are not enabled. The production server terminates TLS at its reverse proxy with a publicly trusted certificate that renews automatically; plain HTTP serves only the redirect to HTTPS and certificate validation. AWS-managed endpoints in the dedicated account (S3, KMS, CloudTrail, Bedrock) enforce TLS 1.2+ by default. Administrative access to the production server travels over SSH-2 inside an encrypted private overlay network.
At rest.
- Customer documents and assistant attachments are stored in Amazon S3 with default server-side encryption (AES-256), object versioning, and account-level Block Public Access — no bucket in the account can be made public. The production server's IAM user may write only to its own object prefixes.
- Database backups are taken daily, kept 14 days on the server, and copied to that same encrypted,
versioned S3 account. Copies in S3 expire under a lifecycle rule on the backup prefix — 25 days as the
current version plus 1 day as a noncurrent version — so every copy is gone within about 30 days; expiry
is performed asynchronously by AWS and can occasionally lag by a few days. The former AWS-hosted
production database (Amazon RDS) and its snapshots were deleted on 2026-10-12. The server's key is
write-only to the backup prefix, so a compromised server cannot read back or destroy earlier copies.
No copy contains the data of the eBay connection tables (
ebay_connection,ebay_oauth_state,ebay_deleted_fingerprint); only their structure is copied (Section 13a). - Amazon SP-API refresh tokens belonging to a selling partner are encrypted at the application layer before they reach the database, and only the ciphertext is stored; the key lives outside the database, in the server's mode-600 configuration file (Section 6). A database copy — including a backup copy in S3 — therefore yields no usable seller token. The same mechanism protects stored multi-factor secrets.
- Customer-managed KMS keys (CMKs) with annual automatic rotation encrypt the AWS account's CloudTrail log bucket and, under a key of its own, the report-archive bucket of Section 7a.
- The data at rest on the production server is held on an encrypted volume. Since September 11, 2026
the PostgreSQL data directory, the mode-600 secrets file (Section 6) and the local backup copies live
inside a LUKS2 container (AES-XTS-512, Argon2id) opened as a device-mapper volume and mounted at
/srv/secure; their former paths are bind-mounted onto it, so no configuration path changed. Swap is a separate device-mapper volume keyed randomly at every boot. The passphrase is not stored on the host and cannot be recovered from it — after a reboot the volume is opened from an operator workstation that holds it, and the database and application units refuse to start until it is mounted. - The operating-system volume itself is not encrypted. It carries no seller data, no secrets and no backups — all three live inside the container above. The compensating controls remain in force: the database listens on the loopback interface only and no database port is reachable from any network (Section 7); every copy of the data that leaves the host — documents and backups — is encrypted (above); the highest-sensitivity values inside the database are additionally encrypted at the application layer (above); and the data held contains no Amazon buyer PII (Section 3).
- Verified, not asserted. On September 12, 2026 that day's backup was restored into a scratch database
on the production host: 56 tables, zero
pg_restorewarnings, and row counts identical to production on every table checked. The scratch database and the working copies were destroyed immediately after the check. The commands and their output are kept as evidence alongside this document (evidence/2026-09-12-encrypted-volume-and-restore-test.md). This closes the commitment made in version 1.4 to move the database onto encrypted storage and verify the move by a restore test.
AES-256, used for every encrypted store above, meets and exceeds Amazon's data-encryption standard (minimum AES-128, AES-256 preferred, or RSA-2048+).
6. Credential & Secrets Management
- Where production secrets live. The production environment's secrets — the SP-API application credentials, Stripe keys, the database connection string, the AWS access key for the S3/Bedrock user, and the application's own encryption secret — are held in a single configuration file on the production server (the internal-integration environment is described in Section 7a), mode 600, owned by the unprivileged account that runs the service, and stored on the encrypted volume described in Section 5. That file sits outside any repository, outside the release artifact, and outside the database backup stream; its values are never embedded in client-side code, committed, or logged in plaintext. An encrypted copy of that file is kept in a password-protected keyring on the operator workstation — the same workstation that holds the encrypted volume's passphrase. Refreshing the copy is a step the operator performs after every change to the file; a forgotten refresh is caught by the quarterly comparison of the copy with the server's file by SHA-256 (Section 13a). The copy is never displayed or written to disk in plaintext, and it is restored only onto a server that does not yet have that file.
- Per-seller LWA refresh tokens are never written in plaintext. Each is encrypted at the application layer under the key held in that configuration file, and only the ciphertext is stored — in a per-connection row scoped to the authorizing customer, so the store itself offers no cross-tenant exposure.
- Bank credentials are never written in plaintext. A bank API key a customer enters (Mercury, Wise) and the access token Plaid issues for a customer's bank connection are encrypted at the application layer under the same key, and only the ciphertext is stored, in a row scoped to the customer's organization. A single-use connection preview holds an encrypted bank API key until the connection is confirmed; it can be used for ten minutes, and an expired preview is deleted the next time a Mercury or Wise connection is previewed or confirmed, or with the customer's account (there is no separate cleanup timer). Plaid's one-time Link token is never stored: only its SHA-256 hash is kept, to bind the Link window, valid for 30 minutes, to the user and organization that opened it. Disconnecting erases a bank API key at once and a Plaid access token as soon as Plaid confirms the revocation. The bank-key client sends only GET requests to allow-listed paths on fixed Mercury and Wise origins and does not follow redirects; the Plaid client calls only Plaid's API for the configured environment. Starting or reconnecting a bank connection, confirming its accounts, disconnecting, deleting bank data, and Sync now require a fresh second factor.
- eBay credentials are never written in plaintext. Where the eBay connection is offered, the refresh token eBay issues for a seller's connection is encrypted at the application layer under the same key, and only the ciphertext is stored. The seller's eBay user ID is never stored: only its HMAC-SHA256 fingerprint under a separate key held in the same configuration file, from which the ID cannot be recovered.
- Rotation. SP-API application credentials and long-lived tokens are rotated at least annually, or immediately upon suspected compromise. The long-lived AWS access key held on the production server is rotated at least every six months — a compensating measure recorded at the September 8, 2026 migration for the automatically rotated container role the application used before it.
- AWS root: no access keys exist for the root user (see Section 4). IAM user credentials are never shared between individuals.
- Repository secrets (CI/CD tokens, deployment credentials) are stored in GitHub's encrypted repository secrets store, scoped to the minimum workflows that require them, and never printed to CI logs.
7. Network Security
- Isolation. Production runs on a single-tenant server dedicated exclusively to Taxller: it hosts no other product, and it is separate from the internal automation environment of Section 7a and from any Amazon seller account.
- Host firewall and exposed surface. The firewall's default inbound policy is deny. Exactly three inbound ports are reachable from the internet: TCP/80 and TCP/443 (the reverse proxy — port 80 serves only the HTTPS redirect and certificate validation), and the overlay network's UDP transport port. The PostgreSQL database listens on loopback only and is reachable from no network; the application process likewise listens on loopback and is reached only through the reverse proxy; SSH is reachable only over the private overlay interface. A guard rule prevents container runtimes from publishing ports around the firewall. This posture was verified by an external port scan at the September 8, 2026 migration and is re-verified whenever the host's service configuration changes.
- Brute-force protection at the edge. Failed-authentication jails read the SSH and web-server logs and ban a source address for one hour (SSH: 4 failed attempts; web sign-in: 12 failed attempts within five minutes). Andivano LLC states plainly that this replaced the managed web application firewall that fronted the application before the migration and is a weaker control at the network edge; the primary defences against credential attack are therefore the per-account lockout, CAPTCHA escalation and server-side delay of Section 4, and step-up re-authentication on sensitive actions — all of which act inside the application regardless of source address.
- Intrusion detection and prevention — host-based. Detection and blocking operate on the host rather than at a managed network appliance, and Andivano LLC states which mechanisms carry that function: log-driven jails inspect the SSH and web-server logs continuously and automatically ban the source address of an attack pattern (Section 7, brute-force protection); the operating system applies security updates automatically (Section 9); a watchdog checks application health every five minutes and restarts a failed service; releases are installed transactionally and roll back automatically when the new version fails its health check; and Amazon GuardDuty provides managed threat detection for the AWS account that holds the document store and Bedrock access. The production server carries no interactive user sessions — no desktop, no shell for anyone but the Managing Member over the private overlay — and the application runs under an unprivileged account whose reach is limited to its own release directory and its mode-600 configuration file. These are the compensating controls for the absence of centrally managed endpoint protection on the server, whose adoption remains the dated commitment at the end of this section.
- Amazon GuardDuty remains enabled account-wide in the Taxller AWS account, providing managed threat detection across the account that holds the document store and Bedrock access, alongside S3 Block Public Access. It no longer observes the application tier, which left AWS on September 8, 2026.
- Availability and integrity monitoring. A watchdog on the production server checks application health every five minutes and, on failure, restarts the service and emails the Managing Member. Releases are installed transactionally and roll back automatically if the new version does not answer its health check.
- Marketing site separation. taxller.com is a static export hosted on Hostinger, entirely separate from
the product's AWS infrastructure and from any seller or customer data — it has no code path that touches
product data. A
security.txtfile is published at/.well-known/security.txtwith the security contact (info@taxller.com). - Endpoint protection — commitment, trigger: first additional device/personnel with system access. The Managing Member's administrative workstation runs OS-native anti-malware protection with automatic signature updates. Before any additional personnel are granted device-level access to systems that handle seller or customer data, Andivano LLC will adopt centrally managed endpoint protection with monthly-or-better update enforcement and controls that prevent end-user disablement.
7a. Internal Integration Environment
Andivano LLC's pre-existing private SP-API integration (Section 1) — used exclusively for its own Amazon seller account and never on behalf of a third-party selling partner — runs on infrastructure separate from the Taxller product's dedicated AWS account described elsewhere in this document. The exception is the storage of its raw report archives, which since 2026-10-03 are held in a bucket of their own in that account, described in the last three items of this section. This section documents that environment's safeguards.
- Hardened Linux host. A Linux VPS, administered solely by the Managing Member. Its one non-administrative local desktop account was disabled on 2026-10-23 (password locked, account expired, its desktop and VNC services stopped; its files are kept so the change can be reversed). The ufw host firewall has been enabled since 2026-10-23: inbound traffic is denied by default, and only SSH (TCP/22), the overlay network's WireGuard port (UDP/41641), and traffic arriving on the overlay-network interface are allowed. The remaining items of finding 2 in the 2026-10-23 access review stay under remediation.
- Key-only SSH. Authentication is by SSH key only; password authentication is disabled at the SSH daemon level.
- Minimal public attack surface. The host exposes exactly one public TCP listener — TCP/22 (SSH).
The only UDP port the host firewall admits from a public address is the overlay network's own
WireGuard NAT-traversal port, which carries no integration service. Every service the integration runs
is bound to loopback (
127.0.0.1) or to the private overlay-network (tailnet) interface, never to a public address. The host's mDNS service discovery was disabled on 2026-08-05, but on 2026-10-23 it was found running again (its service unit is disabled, while its activation socket is active), together with two other wildcard-bound UDP sockets whose owning processes cannot be attributed without administrator rights. The firewall has no rule admitting these ports from a public address; traffic arriving on the overlay-network interface is allowed. Dated evidence of this posture is kept alongside this document and re-checked whenever the host's service configuration changes. The check made after the firewall was enabled — listening sockets, firewall status, and public IPv4 TCP probes from the production server — is recorded inevidence/2026-10-23-quarterly-access-review.md; public UDP and IPv6 reachability were not probed. - Secrets handling. Credentials for this integration (SP-API application credentials, refresh tokens, and any other secrets) are held in a permission-restricted environment file, readable only by the operating-system account that runs the integration, and are never committed to any repository. Credentials in the environment file are rotated at least annually, or immediately upon suspected compromise.
- No buyer PII. Consistent with Section 3, this integration requests and stores no Amazon buyer personal data.
- Logging. systemd journals and application logs capture operational activity for this host.
- Raw SP-API report archives — encrypted at rest in Amazon S3. Since 2026-10-03 every daily report
file the integration writes to its report archive on this host — the archive the 2026-09-10 evidence
counted — is copied to a dedicated Amazon S3 bucket in the Taxller AWS account (
us-east-1), encrypted with SSE-KMS under a dedicated customer-managed key with annual automatic rotation — the scheme Section 5 describes for that account's CloudTrail log bucket. The bucket has bucket-level Block Public Access, object versioning and no expiry rules, and its policy refuses any request made without TLS and any upload that does not name that key. An hourly job copies each report normally within about three hours after its day ends and the file stops changing, and the job's own verification fails if any report that has not changed for more than three hours is not in the bucket under that key with a matching checksum. The host keeps the most recent 35 days of reports, which the operator's own reporting tools read; a report is deleted from the host once it is 35 days old, and only after S3 has confirmed its SHA-256 checksum, size and encryption key and the stored copy has been read back and matched. A run that fails while the host can still reach and authenticate to AWS sends an e-mail alert to the security contact, and the job's state is checked at every bi-weekly log review (Section 8), which is what catches a job that has stopped running or can no longer authenticate. As of 2026-10-04 06:55 UTC the bucket held 211 report files with file dates from 2026-06-08 to 2026-10-03, each confirmed encrypted under the archive key, and the archive directory held no report file older than 36 days; every file there, apart from hidden and temporary files, is classified either as a report or, by the operator, as not one (evidence/2026-10-03-spapi-archive-migration.md). The archives are kept without automatic expiry as Andivano LLC's own accounting records; their retention is reconsidered at the annual review of this plan (Section 14). - Limits of that control. The host's disk is not encrypted: the most recent 35 days of reports remain on it in plain form, and so do the integration's own working files in the same directory — the latest snapshot and a rolling summary of the last 31 days — which are not archived. Other data the operator's tools derive from SP-API and keep elsewhere on this host is not part of this control. Deleting a file there is an ordinary file-system deletion, not a secure erase; it does not reach copies in earlier backups of the host or in the hosting provider's snapshots. Object-level access to the archive bucket is not recorded by CloudTrail; changes to the bucket and the key are. The hourly job runs under the Taxller AWS account's administrative IAM credentials held on this host, which could read or delete not only the archive but any other data in that account, including the customer document store and the database backups.
- Commitment, trigger: 2026-12-31. The hourly job will run under a dedicated identity that can write and read the archive but cannot delete objects or object versions, change the bucket's configuration, or disable or schedule deletion of the key. This narrows the job's own access; the administrative credentials themselves remain on this host for the administration of the account.
8. Logging & Monitoring
| Log source | Retention | Notes |
|---|---|---|
| Production server — systemd journal (application, service, and OS events) | ≥ 12 months | Entries are kept for up to one year (MaxRetentionSec=1year) under a 4 GB size cap; disk usage is checked at the bi-weekly log review so that the cap never shortens retention below the 12-month minimum in Amazon's SP-API logging and monitoring guidance. |
| Production server — reverse-proxy access log | ≥ 12 months | A separate JSON log file written by the reverse proxy, rotated at 50 MiB and kept for up to 366 days (roll_keep_for) under a 40-file cap. At the measured volume (under 1 MB a day in September 2026) the cap holds several years, so the 366-day limit is the one that applies; volume is re-checked at the bi-weekly log review. Records request metadata, not request bodies. |
| Application security events, in PostgreSQL (sign-in attempts and lockouts, session creation and revocation, security e-mails sent, account activity feed) | ≥ 12 months | Included in the daily encrypted backup, so the record survives replacement of the host. |
Jev decision-model calls — one structured line jev.usage per call in the application journal |
≥ 12 months | Scenario (use), outcome, number of questions, latency (ms), and input and output token counts; never the text sent or received, never the key. |
| SP-API data-access journal — commitment, trigger: first selling-partner authorization | ≥ 12 months | Which selling partner, which data window, which outcome, for every synchronisation run; specified together with the seller-connection feature and retained at least twelve months. |
| AWS CloudTrail (all-regions trail) → dedicated S3 bucket, SSE-KMS | ≥ 365 days (bucket lifecycle policy) | Covers the AWS account that holds the document store and Bedrock access. |
- Alerting. On the production server, the health watchdog emails the Managing Member when the service fails or is restarted, and the release mechanism reports any failed or automatically rolled-back deployment. In the AWS account, an EventBridge rule watches for root-account sign-in and unauthorized/denied API calls and publishes to an SNS topic that emails info@taxller.com; that email subscription is confirmed and end-to-end delivery has been tested.
- Review cadence. The Managing Member reviews the production server's authentication and error logs, CloudTrail and GuardDuty findings, and the Section 7a archive job's verification output and timer state, at least bi-weekly and immediately upon any automated alert — meeting Amazon's minimum bi-weekly review cadence for organizations without a dedicated SIEM.
- Log content. Logs are not designed to capture buyer PII (moot today, since Taxller collects none) and application logging excludes customer PII and secrets by default, consistent with Amazon's requirement that logs exclude PII unless legally required. Model-invocation logging is disabled in the AI assistant's Bedrock configuration, so customer conversations are not retained by that service.
- Budget anomaly alerting. An AWS Budgets alarm notifies info@taxller.com if account spend crosses a defined monthly threshold, acting as an additional signal for anomalous or unauthorized resource use.
Note on a documentation discrepancy: Amazon's SP-API Security and Compliance Overview index page states a general "90-day minimum" log retention figure, while the dedicated Logging and Monitoring guidance page specifies "at least 12 months." Andivano LLC treats the dedicated page's 12-month figure as authoritative and has sized production-server journal retention, database-resident security records, and CloudTrail retention to satisfy the stricter figure.
9. Vulnerability Management
Amazon's 30-day scan / annual pentest / 7-day-critical remediation requirements are scoped under the Data Protection Policy's PII-Additional controls (§2.7). Because Taxller's SP-API scope excludes buyer PII by design (Section 3), these controls are not strictly mandated for the current application. Andivano LLC nonetheless applies the following, in recognition that the product still handles sensitive business and tax data:
-
Already in place: Dependabot vulnerability alerts are enabled on the product repository, so a newly published advisory against any dependency raises an alert without waiting for a scheduled scan, and Dependabot's weekly version updates open pull requests that bring dependencies current; CI quality gates (lint, typecheck, tests) run on every pull request, so code-level scanning precedes every release; and the production server applies operating-system security updates automatically through unattended upgrades.
-
Scheduled dependency scanning — in place from this version's effective date. A scheduled job in the product repository scans the application's full resolved dependency tree against public vulnerability databases at least every 30 days, and again on every change to the lockfile. Findings are triaged by the Managing Member on the same cadence as Dependabot alerts.
-
Commitment — trigger: before Taxller ingests SP-API data belonging to any selling partner other than Andivano LLC. Andivano LLC will add an authenticated infrastructure vulnerability scan of the production host on the same 30-day cadence, and commission a third-party penetration test of the application, repeated at least annually thereafter. Their findings fall under the remediation timelines below.
-
Remediation timelines — in force from 2026-10-20. Every identified vulnerability in Taxller's production systems or their dependencies — whether raised by Dependabot, the scheduled dependency scan, an operating-system advisory, an inbound report (Section 13), or any other source — is triaged by the Managing Member and remediated within 7 days of discovery if critical-risk and within 30 days if high-risk, matching Amazon's stated thresholds. Remediation means a patch or upgrade, or, where none is available yet, a documented compensating control kept until one is. Medium- and low-risk findings are handled in the normal maintenance cycle. Until version 1.16 these timelines were a future commitment tied to the trigger above; they now apply to all findings.
-
End-of-life software. The inventory below is reviewed every quarter together with the access review. An upgrade is planned no later than six months before end of support. A component past end of support without vendor security fixes is treated as a high-risk vulnerability under the 30-day remediation deadline above. The table names release lines; exact installed versions are recorded in each review's evidence.
Component Release line in use Where End of support Ubuntu LTS 26.04 Production server Standard support 2031-05-29; ESM 2036-04-23 Node.js 24 (LTS) Production server Maintenance LTS EOL 2028-04-30 PostgreSQL 18 Production server 2030-11-14 Next.js 16 Production application No EOL date published; 16 is supported Caddy 2 Production server No fixed EOL date; verify installed release is vendor-supported each quarter ClamAV 1.5 Production server No fixed EOL date; verify installed release is vendor-supported each quarter Tailscale 1.x Production server No fixed EOL date; verify installed release is vendor-supported each quarter OpenSSH 10 Production server No fixed EOL date; verify installed release is vendor-supported each quarter Ubuntu LTS 24.04 Section 7a host Standard support 2029-05-31; ESM 2034-04-25 Node.js 24 (LTS) Section 7a host Maintenance LTS EOL 2028-04-30 Tailscale 1.x Section 7a host No fixed EOL date; verify installed release is vendor-supported each quarter OpenSSH 9 Section 7a host No fixed EOL date; verify installed release is vendor-supported each quarter
10. Secure Development
- CI/CD gates. Every pull request to the product repository runs lint, typecheck, and test jobs, and changes are merged only after these checks pass. The production release workflow enforces this technically: it refuses to build a release from a commit whose CI run is not green, so no change reaches production without passing the gates.
- Change path. Changes land on the default branch through pull requests. GitHub's branch-protection rules are not available for this private repository on its current GitHub plan, so this rule is held by practice and by the release gate above rather than by a repository setting. Only one GitHub account — the Managing Member's, through which the development tooling also acts — has write access to the repository, and it requires multi-factor authentication (Section 4). Versions of this plan before 1.16 described the default branch as protected against direct pushes; that was inaccurate and is corrected here.
- Dependency management. Dependabot is configured on the repository to open weekly update PRs for outdated dependencies, which then pass through the same CI gates before merge; its vulnerability alerts flag vulnerable dependencies, which are fixed under the remediation timelines in Section 9.
- Secrets hygiene. No credentials, API keys, or tokens are committed to the repository; local secret files are git-ignored, and CI/deployment secrets live in GitHub's encrypted secrets store or in the production server's mode-600 configuration file (Section 6).
11. Data Retention & Deletion
Taxller production holds customer account data, questionnaire answers, seller-uploaded documents, and bank-import records (early access, since August 2026). Customer-facing retention and deletion commitments are stated in the Privacy Policy (taxller.com/legal/privacy) and honored by manual request handling. The following retention posture applies to infrastructure and operational data:
- Infrastructure and application logs: per Section 8 — production-server journals and database-resident security records for at least 12 months, AWS CloudTrail for at least 365 days.
- Database backups: 14 days on the production server; in S3 the lifecycle rule in Section 5 removes
every copy within about 30 days (25 + 1 days, AWS may lag). Checked monthly:
python3 infra/documents/provision.py --step statusmust printbackups: OK(no version or delete marker older than 30 days) withnewest=under 26 hours (the server still writes a nightly copy). - SP-API seller data: once ingestion begins, seller financial/inventory/order/fulfillment data is retained only as long as necessary to provide the service to that seller or as required by applicable tax-recordkeeping law, whichever is longer.
- Account closure / SP-API de-authorization: upon a seller disconnecting their Amazon account or closing their Taxller account, associated seller data and credentials (including the stored, encrypted refresh token) are deleted within 30 days, absent a legal requirement to retain longer.
- Bank data: disconnecting a bank erases its stored key or, once Plaid confirms the revocation, its Plaid access token; Delete bank data erases the connection's raw Plaid data and its unposted rows that no other connection also supplied, while posted rows, book entries, the account list, and the connection's own record stay (Privacy Policy, Section 7). Account deletion revokes the Plaid connections before the account's data is deleted.
- eBay connection data: when eBay notifies Taxller that a seller's eBay account has been closed or deleted, the encrypted refresh token and the fingerprint are erased immediately and permanently in every connection of that seller, and the channel shows the eBay account as closed; files the customer uploaded and book entries are not affected. The fingerprint of the deleted account is kept in a separate technical register for at most 48 hours, until the daily cleanup deletes it, so that a connection made at the time of the deletion cannot store the account's data again. eBay connection data is also deleted within 30 days of a request to info@taxller.com and with the Taxller account. Database backups contain no eBay connection data (Section 5), so a restore cannot bring back data erased after an eBay notice (Privacy Policy, Section 7).
- Published customer-facing policy. The retention and deletion policy is published in Taxller's Terms of Service and Privacy Policy (taxller.com/legal), which state the 30-day rule for SP-API data following a deletion request, de-authorization, or account closure. This fulfils the commitment made in version 1.0 of this plan, whose trigger — first customer onboarding — was reached in August 2026.
12. Subprocessors
| Subprocessor | Purpose | Data involved |
|---|---|---|
| Amazon Web Services, Inc. | Encrypted S3 object storage for customer documents and assistant attachments; Amazon Bedrock (US regions only) for the AI assistant; CloudTrail and GuardDuty for that account; S3 storage of the Section 7a report archives; S3 storage of the encrypted database backups (Section 5) | Customer documents and attachments; the content of assistant conversations at inference time — model-invocation logging is disabled and the data is not used to train models; Andivano LLC's own SP-API report files (no buyer personal data); database backup copies, which include bank-import records |
| TypeSafe AI, Inc. | Jev decision model for AI suggestions and checks, on AWS in Oregon (us-west-2); returns probabilities, not text; only for users who accepted the Privacy Policy of 2026-10-11 or later; emergency off: clear TYPESAFE_API_KEY |
Limited, cleaned text listed in Privacy Policy Section 13 — never uploaded documents, SP-API data, balances, full account or card numbers (cards masked to the last four digits), or amounts and dates as separate fields; typed free text may keep numbers or dates. Zero Data Retention: request and answer texts are not stored, only operational telemetry; not used to train models |
| Plaid Inc. | Bank connections through Plaid Link and the Transactions product, for customers who choose them; the customer signs in to the bank in Plaid's window, where Plaid acts under its own End User Privacy Policy | A pseudonymous organization identifier, the chosen history period, Taxller's webhook address, and the settings of the Link window; the tokens Plaid issued, sent back to complete the connection, fetch updates, or remove it. Plaid returns account names, types, last four digits, currencies, and balances, and transactions; Taxller stores transactions only for US-dollar deposit and credit-card accounts and deletes them for an account the customer chooses not to import. Taxller never receives bank sign-in credentials |
| ExtraVM LLC | Hosting of the production server (United States) | Hosting of the application and its database. The provider is not granted administrative access to the application, its database, or its secrets |
| Stripe, Inc. | Subscription billing and payment processing — live since August 22, 2026 | Payment/billing data; card data is handled entirely within Stripe's PCI DSS-compliant environment and never touches Taxller infrastructure |
| Resend | Transactional email delivery (security notifications, invitations, billing receipts) | Recipient address and message content of transactional email; no seller operational data |
| Cloudflare, Inc. | CAPTCHA challenge (Turnstile) on authentication surfaces | Challenge metadata only; no account, customer, or seller data |
| Google LLC | Optional "Sign in with Google" federated authentication, for customers who choose it | Sign-in identity (verified email address) only |
| GitHub, Inc. | Source repository, continuous integration, and release-artifact distribution | Source code and build artifacts; no customer or seller data |
| Hostinger | Static hosting for the public marketing site (taxller.com) | Public marketing content only — no product, seller, or customer data |
| Have I Been Pwned (HIBP) | Password breach screening at registration and on every password change or reset | The first five characters of the password's SHA-1 hash (k-anonymity range query); never the password, the account or any seller data |
| Internal accounting server provider (United States) | Virtual private server on which Andivano LLC keeps its own books | Copies of the invoice and credit-note PDFs Taxller issues to its customers and the related billing register; no Taxller customer's seller operational data. The same server is the Section 7a host: it also holds the most recent 35 days of Andivano LLC's own SP-API report files, the integration's working files, and other data the operator's tools derive from SP-API (Section 7a) |
Customer and seller data at rest — documents, the production database, and its backups — resides in the United States, and the AI assistant's inference profile is pinned to US regions. Subprocessors that carry no customer or seller data (marketing-site hosting, CAPTCHA) are listed for completeness.
The Amazon SP-API itself is the data source under each seller's own authorization, not a subprocessor of Andivano LLC. Likewise, Mercury and Wise, when a customer connects them with an API key the customer creates, are data sources under the customer's own authorization, not subprocessors; Taxller sends them only that key and read requests. eBay, when a seller connects it on eBay's own consent screen, is likewise a data source under the seller's own authorization, not a subprocessor; Taxller sends eBay only requests authenticated with Taxller's eBay application keys or with a token eBay issued.
13. Incident Response
Operational incident-handling procedures (detection, containment, eradication, recovery, and communication) are defined in the companion Incident Response Runbook, committed to this same repository, version 1.3, effective 2026-09-13. The runbook defines the incident-commander and communication roles, and is reviewed at least every six months — the next review is due no later than 2027-03-13 — and additionally after any SEV1 incident and after any material change to the infrastructure it describes.
- Amazon notification. In the event of a security incident affecting SP-API data, credentials, or application access, Andivano LLC notifies Amazon at security@amazon.com within 24 hours of detection, per the Data Protection Policy's Risk Management and Incident Response Plan requirement.
- Plaid notification. If a security breach compromises Taxller's systems, or does or reasonably could compromise the security, integrity, or confidentiality of data received through Plaid, Andivano LLC notifies Plaid promptly and in no event more than 12 hours after becoming aware of it — through a support request in the Plaid Dashboard and by email to legalnotices@plaid.com — describing the known facts and the types of end users affected, and cooperates with Plaid's investigation and remediation, as Andivano LLC's agreement with Plaid requires.
- Escalation. As a single-member LLC, the Managing Member is the sole incident commander and point of contact; there is no additional internal escalation chain today. This will be expanded as additional personnel join.
- Customer/regulatory notification. Taxller has customers in early access, so this is an active obligation rather than a future one. On a confirmed breach of customer or seller data, Andivano LLC notifies each affected customer without undue delay, at the email address on their account, stating what happened, which categories of data were involved, and what the customer should do; and makes any regulatory notification required by applicable United States state breach-notification law. The operational procedure is carried in the Incident Response Runbook.
- Contact. info@taxller.com is the published security contact (also listed in
/.well-known/security.txton the marketing site).
13a. Business Continuity & Disaster Recovery
This section is the continuity and recovery plan for the loss of the production server or of the data on it. As in Section 13, the Managing Member owns the plan, decides when it is invoked, and carries it out.
- Objectives. Recovery point objective: RPO ≤ 24 hours — the database is copied once a day. A failed copy is detected by the watchdog, which e-mails the Managing Member when the newest copy is more than 26 hours old, and by the monthly check of Section 11. Recovery time objective: RTO ≤ 48 hours to bring the product back on a new server, provided that the operator workstation is available.
- What depends on the operator workstation. It holds the encrypted volume's passphrase (Section 5),
the encrypted copy of the production secrets file (Section 6), and the base host-preparation scripts
for a new server. Everything else the rebuild needs is in the product repository under
infra/vps/: the service and timer units with their encrypted-volume drop-ins, the backup, watchdog, cleanup and antivirus scripts, the reverse-proxy configuration and the SSH, firewall, failed-authentication jail, kernel and journal-retention settings (infra/vps/host/), and the encrypted-volume and release scripts. After every reboot of the production server, the database, the application and the daily copy do not start until the volume is opened from the workstation (Section 5); if the server reboots while the workstation is unavailable, the product stays down until the workstation is restored. - If the workstation is lost together with the server. The encrypted volume is lost with the server,
so its passphrase no longer matters. Two things are lost that matter: the production secrets file, and
the base host-preparation scripts, so steps 1 and 2 below are then carried out by hand from their
description in this section and in
infra/vps/. What survives: the database copies in S3, reached through the AWS console sign-in with its second factor (Section 4); customer documents and assistant attachments in S3; the releases on GitHub; and the host files in the repository. Without the key in the secrets file, the tokens and multi-factor secrets encrypted in the database cannot be read: sellers reconnect Amazon, their banks and eBay; a user with an enrolled authenticator, which must be verified at every new session, can sign in again only after support resets it underdocs/MFA-RESET.md(Section 4 of this plan); and the application's secrets are obtained again from their issuers. - What is copied, and where.
- Database: every day at 04:30 server time (America/New_York), a compressed
pg_dumpin custom format, about 15 MB, kept for 14 days on the server's encrypted volume and uploaded to S3 with AES-256 server-side encryption, where the lifecycle rule of Section 5 removes it within about 30 days. - eBay connection data: not copied. Only the structure of
ebay_connection,ebay_oauth_stateandebay_deleted_fingerprintenters a copy, so data erased after an eBay notice cannot come back through a restore; after a restore, sellers reconnect eBay. - Production secrets file: outside the database copies; an encrypted copy is kept in a password-protected keyring on the operator workstation, refreshed by the operator after every change; a forgotten refresh is caught by the quarterly SHA-256 comparison (Section 6).
- Customer documents and assistant attachments: in S3 with object versioning (Section 5).
- Application: every production release is published as a GitHub Release of the product repository (Section 12).
- Database: every day at 04:30 server time (America/New_York), a compressed
- Restoring the production server. Each step ends with the check that must pass before the next one.
- New host. A new server from a US hosting provider, running Ubuntu 26.04 LTS (Section 9), receives
the base configuration of the host-preparation scripts on the operator workstation: named login
accounts with SSH keys, key-only SSH, a default-deny host firewall, failed-authentication jails and
automatic security updates. It then joins the private overlay network, and the production versions
of these settings are installed from
infra/vps/host/: the SSH daemon settings (etc/ssh/sshd_config.d/), the ufw rules (etc/ufw/), which admit SSH only on the overlay interface, the SSH jail (etc/fail2ban/jail.d/99-taxller-sshd.local), the kernel settings (etc/sysctl.d/) and the one-year journal retention of Section 8 (99-taxller-log-retention.conf, installed as/etc/systemd/journald.conf.d/99-taxller-cap.confin place of the base preparation's one-month cap). Public SSH is then closed (Sections 4 and 7). Check: SSH accepts keys only and answers only on the overlay interface. - Software and encrypted volume. The host-preparation scripts install Node.js 24, PostgreSQL 18,
the reverse proxy and the overlay-network client. A standard LUKS2 volume with the parameters in
infra/vps/ENCRYPTION.md(20 GB, AES-XTS with a 512-bit key, Argon2id) and a new passphrase, kept on the operator workstation, is mounted at/srv/secure; the database directory, the directory of the secrets file and the local backups are bind-mounted onto it, and swap is keyed randomly at every boot (Section 5). The unlock and lock scripts come frominfra/vps/, and the units' encrypted-volume drop-ins frominfra/vps/host/andinfra/vps/luks-dropins/. Check: while the volume is locked, the database unit does not start; after it is unlocked, it does (the application, backup and release units, installed in step 5, are checked the same way in step 8). - Database. The application's database role is created with a newly generated password, and the
database, owned by that role, with its locale set explicitly to
en_US.UTF-8, as in production, because the base preparation would otherwise give itC.UTF-8. The latest copy is taken from the old server if it can still be read, otherwise from S3 with the administrative AWS access (Section 4), because the server's own key cannot read copies back. It is restored withpg_restore --no-owner --no-privileges, as in the 2026-09-12 test (Section 5), with--roleset to the application's role, so that the role owns every restored object. Check:pg_restorereports zero warnings, every table in the copy's table of contents is present, and every table is owned by that role. - Secrets file. The operator's encrypted copy is restored onto the new server — only while no secrets file is there — as mode 600, owned by the account that runs the service; the database connection string is then changed to the new role password. Check: before that change, the file's SHA-256 matches the copy; after it, the copy is refreshed (Section 6).
- Application. The application unit and the backup, watchdog, daily cleanup and antivirus units
and scripts are installed from
infra/vps/host/, and the daily Amazon book sync (taxller-books-sync) frominfra/vps/. The release mechanism (infra/vps/) is installed with a newly issued read-only GitHub token. It installs the latest GitHub Release transactionally, restarts the service and confirms it, or rolls back (Section 7). Nothing is built on the server. Check: the new process reports the installed release tag, and its health check answers 200. - DNS. The A record of
app.taxller.com(TTL 300 seconds) is pointed at the new server. Check: the name resolves to the new address. - Reverse proxy and TLS. The reverse-proxy configuration from
infra/vps/host/etc/caddy/Caddyfile, bound to the new server's public address instead of the old one — it forwards to the application on loopback and writes the access log of Section 8 — is switched on only after step 6 and once the application is listening, so that the publicly trusted certificate is issued on the first attempt. The web sign-in jail of Section 7, which reads that access log (etc/fail2ban/jail.d/taxller-web.localwithetc/fail2ban/filter.d/taxller-web.conf), is installed with it. Check: the certificate forapp.taxller.comis valid, and plain HTTP only redirects to HTTPS. - Health checks. The readiness check answers 200 through the public domain; an external port scan
finds only the ports listed in Section 7; ufw reports itself active; the
sshdandtaxller-webjails are running; the journal configuration readsMaxRetentionSec=1year; with the volume locked, the application, backup and release units do not start, and after unlocking they do; the watchdog, backup, daily cleanup, release, Amazon book sync and antivirus timers are active; and the first copy written by the new server reaches S3 (backups: OKwithnewest=under 26 hours, Section 11). - Access keys issued or set again. The read-only GitHub release token; the server's overlay-network enrollment, whose key expiry the watchdog warns about; the SSH keys authorized on the new server; the encrypted volume's passphrase; the database role password; the server's overlay address in the operator workstation's unlock job; and the watchdog's e-mail setting, which is kept outside the encrypted volume so that it can alert while the volume is locked. If the old server may have been compromised, every secret in the secrets file is rotated as well (Section 6). The Stripe webhook and the Facebook sign-in return address are tied to the domain and stay unchanged while it does. Check: a reboot of the new server brings the database and the application back without manual action.
- New host. A new server from a US hosting provider, running Ubuntu 26.04 LTS (Section 9), receives
the base configuration of the host-preparation scripts on the operator workstation: named login
accounts with SSH keys, key-only SSH, a default-deny host firewall, failed-authentication jails and
automatic security updates. It then joins the private overlay network, and the production versions
of these settings are installed from
- Testing. A copy is restored into a scratch database on the production server at least once a
quarter and before every change on which recovery depends; the scratch database is destroyed after
the check. The last test was on 2026-10-26, before the eBay production keys were issued
(
evidence/2026-10-26-restore-test.md); tests run at least once a quarter, the nearest no later than 2027-01-25. The same quarterly check compares the operator's copy of the secrets file with the server's file by SHA-256. The result of each check is recorded indocs/security/evidence/. A full rebuild on a new server has not yet been rehearsed end to end.
14. Policy Review
This WISP is reviewed at least annually, and additionally whenever there is a material change to Taxller's infrastructure, roles/responsibilities, subprocessors, or applicable Amazon/legal requirements. The next scheduled review is due no later than 2027-08-04. Each review also reconsiders the retention of the Section 7a report archive, which has no automatic expiry.
An annual risk assessment of Taxller's systems, data flows, and vendors/subprocessors (Section 12) is conducted alongside this review and its outcome is approved by the Managing Member — consistent with the Data Protection Policy's risk-management requirement (§1.6) and its vendor risk-assessment expectation (§2.8). The first assessment is due together with the first scheduled review, no later than 2027-08-04.
Version History
| Version | Date | Approved by | Summary |
|---|---|---|---|
| 1.0 | 2026-08-04 | Managing Member, Andivano LLC | Initial WISP, aligned to the AWS security baseline established in Taxller's dedicated AWS account and to Amazon's SP-API Data Protection Policy guidance. |
| 1.1 | 2026-08-04 | Managing Member, Andivano LLC | Scope (Section 1) rewritten to cover all seven roles approved on Andivano LLC's SP-API developer profile — the four Taxller public-application roles plus three additional roles (Product Listing, Pricing, Brand Analytics) used only for Andivano LLC's own seller account under a pre-existing private integration; added Section 7a documenting that integration's hardened-host environment; updated Section 3's PII-exclusion note to the seven-role total; published this document on the public /security page. |
| 1.2 | 2026-08-05 | Managing Member, Andivano LLC | Section 7a's attack-surface statement made precise: the host exposes exactly one public TCP listener (SSH), and the three wildcard-bound UDP sockets — the overlay network's WireGuard NAT-traversal port and the host desktop's mDNS discovery, neither of which carries an integration service — are now named in the text rather than only in the port-scan evidence file it references. No control changed; the previous wording said "one public network listener" without qualifying TCP, which a reader comparing it against a live ss capture would read as inaccurate. |
| 1.3 | 2026-08-05 | Managing Member, Andivano LLC | Section 7a updated after remediation: the host's mDNS service discovery (avahi) was disabled as unnecessary to this host's function, leaving exactly one public TCP listener (SSH) and one wildcard-bound UDP socket (the overlay network's WireGuard transport). Port-scan evidence for 2026-08-05 now contains both the before and after captures. |
| 1.4 | 2026-09-11 | Managing Member, Andivano LLC | Brought the plan to the September 2026 state of the product. Production was migrated off AWS onto a dedicated single-tenant Linux server on 2026-09-08, so Sections 1, 4, 5, 6, 7, 8 and 12 were rewritten to describe the server (firewall posture, loopback-only database, key-only SSH over a private overlay, failed-authentication jails, transactional releases with automatic rollback, daily encrypted backups) and to scope the remaining AWS footprint to the S3 document store and Amazon Bedrock. Three statements that had become untrue were corrected rather than left standing: paid subscriptions are live (since 2026-08-22) and payment data is processed by Stripe; the account-lockout control promised in 1.0 is implemented and is now described as delivered; and Taxller has customers, so customer and regulatory breach notification is an active obligation. Newly stated plainly: the production server's own disk volume is not encrypted at rest, and the managed web application firewall was not replaced in kind — both carry compensating controls and a dated commitment. Added scheduled 30-day dependency scanning; added the payment-data class and the full subprocessor list (hosting provider, Bedrock, Resend, Cloudflare Turnstile, Google sign-in, GitHub). |
| 1.5 | 2026-09-12 | Managing Member, Andivano LLC | Corrected Section 5 to the state of the host after September 11, 2026. Version 1.4 stated plainly that the production server's volume was not encrypted at rest and committed to moving the database onto encrypted storage before ingesting another selling partner's data; that move was carried out on 2026-09-11 and the plan had not caught up. The database, the mode-600 secrets file and the local backups now sit inside a LUKS2 container (AES-XTS-512, Argon2id) whose passphrase is not held on the host, with swap on a separately keyed volume; the operating-system volume remains unencrypted and is described as carrying none of that data. The commitment is closed by a restore test run on 2026-09-12 — 56 tables, zero warnings, row counts identical to production — whose commands and output are kept in evidence/2026-09-12-encrypted-volume-and-restore-test.md. |
| 1.6 | 2026-09-12 | Managing Member, Andivano LLC | Section 4 now states the password policy for Taxller accounts themselves, not only for administrative access: 12-character minimum (raised from 8 the same day, to meet Amazon's baseline), four character classes, breached-password rejection, 10-password history, 365-day maximum age enforced at sign-in, and mandatory TOTP MFA. Added so that the plan, the developer-profile questionnaire and the running product describe one policy. |
| 1.7 | 2026-09-13 | Managing Member, Andivano LLC | Corrected Section 1 to the SP-API structure actually being built. Version 1.6 said Andivano LLC was applying to move its single developer profile to Public; that plan was dropped on 2026-09-12 in favour of a second Solution Provider Portal account held by the same legal entity, so that a review of the public application can never reach the seven approved roles the company's own trading depends on. The original profile stays Private and unchanged, and the new account requests only the four roles Taxller uses. Also recorded the read-only boto3 equivalent of the AWS baseline verification script, which produced the 2026-09-13 evidence. |
| 1.8 | 2026-09-13 | Managing Member, Andivano LLC | Corrected two statements that the code and the host contradicted. Section 4 said TOTP multi-factor authentication was mandatory for every Taxller account; it has been optional for general dashboard access since an owner decision of 2026-08-16 (apps/web/lib/server/session-gates.ts). The section now states what is enforced: verification on every new session once enrolled, an e-mailed single-use code for a password sign-in without an authenticator, and an enrolled authenticator verified within five minutes before an Amazon account can be connected. Section 8 said the reverse-proxy access log was the same journal as the systemd journal; it is a separate JSON file, rotated at 50 MiB, which on 2026-09-13 was also set to keep rotated files for up to 366 days under a 40-file cap. Evidence: evidence/2026-09-13-log-retention-and-mfa.md. Also brought forward facts the plan had not recorded: the IAM password policy expires passwords after 90 days and blocks reuse of the last 24; the Amazon step-up applies when an authorization starts, which must then complete within ten minutes; the journal and proxy-log retention rows now name their size caps and how those caps are checked; Section 12 lists Have I Been Pwned and the internal accounting server, which the Privacy Policy already names; Section 3 and Section 13 now match Section 1 and the runbook's current version. |
| 1.9 | 2026-09-22 | Managing Member, Andivano LLC | Named the controls that answer three questions on Amazon's Solution Provider questionnaire, so the answers and this document say the same thing. Section 7 now states plainly that intrusion detection and prevention are host-based — log-driven jails that ban an attacking source automatically, automatic operating-system security updates, a five-minute health watchdog, transactional releases with automatic rollback, and GuardDuty for the AWS account — and names the production server's compensating controls (no interactive sessions, unprivileged service account) for the absence of centrally managed endpoint protection there. Section 4 states the net effect of the existing multi-factor rules: every account through which Amazon Information can reach Taxller holds an enrolled authenticator verified within the preceding five minutes, while organisational and administrative access requires multi-factor authentication without exception; multi-factor authentication remains optional for a dashboard account that has connected nothing. Section 13 brings forward the Incident Response Runbook's review cadence — at least every six months, next no later than 2027-03-13, and after any SEV1 incident. No control changed; the plan now describes controls it already had. |
| 1.10 | 2026-10-01 | Managing Member, Andivano LLC | The commitment in Section 7a to move the private integration's raw SP-API report archives off the Section 7a host's local disk into Amazon S3 with SSE-KMS encryption, made in version 1.1 with a trigger of 2026-09-30, was not met. It is restated with a trigger of 2026-10-15 and now says where the archives will go (a dedicated bucket under a dedicated customer-managed key with annual rotation in the Taxller AWS account), that the host's local disk is not encrypted, when a local copy may be deleted, and that reports written afterwards will be moved by an hourly job. Because that bucket will sit in the Taxller AWS account, Section 7a's opening paragraph and the descriptions of that account in Sections 1 and 4 name it as a planned exception, and Section 1 no longer says that the product and the company's own trading share no point of failure; they still share no SP-API review surface and no SP-API credentials. Section 4 no longer says the account was created "solely" for Taxller. The word "dedicated" was dropped from the description of the Section 7a host in Sections 1 and 7a, because the host does not serve this integration alone. Section 1 now refers to Section 13 for the Incident Response Runbook's version and effective date instead of saying the runbook shares this plan's effective date. No control changed. |
| 1.11 | 2026-10-04 | Managing Member, Andivano LLC | The Section 7a commitment restated in version 1.10 was carried out on 2026-10-03, except that the host keeps the most recent 35 days of reports, because the operator's own reporting tools read them. The private integration's daily report archive — the one counted in the 2026-09-10 evidence — is now held in a dedicated S3 bucket of the Taxller AWS account under SSE-KMS with a dedicated customer-managed key; an hourly job copies new reports, its verification fails if a report that has not changed for more than three hours is missing from the bucket, and a local copy is deleted at 35 days only after the stored copy is confirmed. Section 7a states that control, its scope (other SP-API-derived data on the host is outside it), that the archive is kept without automatic expiry, how a failed or stopped job is detected, and its limits (unencrypted host disk without secure erase, the integration's unarchived working files, no object-level CloudTrail record, and administrative credentials on the host that could reach all data in the account), with a commitment to move the job to a dedicated identity by 2026-12-31. Section 4 now says which access is protected by multi-factor authentication (console and source-repository sign-in) and which is not (programmatic and key-based access, including access keys and SSH keys), instead of claiming all administrative access is; Appendix A follows. Sections 1, 4 and 12 now refer to the archive bucket, and Section 12's row for the accounting server notes that it is the Section 7a host and what it holds, and now excludes only Taxller customers' seller operational data instead of all seller data; Section 5 and Appendix A now include the archive key; Section 1 names the archive tool's verify output among the evidence; Section 8's review cadence and Section 14's annual review now include the archive job and its retention. |
| 1.12 | 2026-10-11 | Managing Member, Andivano LLC | Section 12 adds TypeSafe AI, Inc. as a subprocessor: its Jev decision model returns probabilities, not text, for Taxller's AI suggestions and checks, is called only for users who have accepted the Privacy Policy of 2026-10-11, and is switched off in an emergency by clearing its key in the production configuration. Section 8 adds the application journal's one line per Jev call, which records counters only, never the text sent or received or the key. |
| 1.13 | 2026-10-12 | Managing Member, Andivano LLC | Section 4 no longer says that every account through which Amazon Information can reach Taxller holds an enrolled authenticator verified within the preceding five minutes. That holds when an Amazon authorization starts, but a user can later turn multi-factor authentication off without revoking the authorization. The section now states the rule as a requirement at authorization time and says what can happen afterwards: turning multi-factor authentication off does not revoke an existing authorization, and support resets a lost authenticator only under docs/MFA-RESET.md, which checks the user's identity, waits at least 24 hours after the user's confirmation, needs the Managing Member's approval for the first e-mail and for the reset, and stops on an active Amazon authorization until the Managing Member decides. The developer-profile questionnaire already stated the rule as a requirement before an Amazon authorization can start. No control changed. |
| 1.14 | 2026-10-19 | Managing Member, Andivano LLC | Adds a retention control for database backups: copies in S3 now expire under a lifecycle rule (25 days current plus 1 day noncurrent), so information deleted from the production database leaves every backup within about 30 days, subject to AWS's asynchronous expiry; Section 11 adds the monthly check that proves it. The AWS resources left from the pre-September production (Amazon RDS with its snapshots, container service, load balancer, image registry and related roles and parameters) were deleted on 2026-10-12; the S3 document store, Amazon Bedrock, CloudTrail and GuardDuty stay. |
| 1.15 | 2026-10-20 | Managing Member, Andivano LLC | Sections 3, 6, 11, and 12 add bank import: customer bank data is classified as Confidential; bank API keys (Mercury, Wise) and Plaid access tokens are encrypted at the application layer like SP-API refresh tokens; Plaid's Link token is kept only as a hash; disconnecting erases the key or, after Plaid confirms the revocation, the token; Delete bank data erases a connection's raw Plaid data and its unposted rows that no other connection supplied; sensitive bank actions require a fresh second factor. Plaid Inc. is added as a subprocessor; Mercury and Wise are recorded as data sources under the customer's own authorization. The AWS row now names the S3 storage of the encrypted database backups described in Section 5. |
| 1.16 | 2026-10-20 | Managing Member, Andivano LLC | Corrections made while answering Plaid's security questionnaire. Sections 9 and 10: Dependabot vulnerability alerts are now enabled on the repository (earlier versions described vulnerability scanning by Dependabot while its alerts were switched off; they were enabled on 2026-10-20); the 7-day critical / 30-day high remediation timelines now apply to every identified vulnerability from 2026-10-20 instead of only after the third-party-seller trigger. Section 10: the default branch is not protected by a GitHub setting (unavailable for this private repository on its current plan); the section now says so and names what does hold the rule — merge practice, the release workflow that refuses commits without green CI, and a single MFA-protected account with write access. Section 13: Plaid is notified of a security breach within 12 hours, as the Plaid agreement requires. |
| 1.17 | 2026-10-23 | Managing Member, Andivano LLC | Section 4 names the bank-connection actions requiring fresh verification, clarifies that the start-of-authorization timing applies to the Amazon rule only, and records the first quarterly access review and next due date. Section 7a records the non-administrative desktop account and disabled ufw host firewall under remediation. Section 9 adds a quarterly software end-of-life inventory by release line and an upgrade rule. The supporting review is evidence/2026-10-23-quarterly-access-review.md. |
| 1.18 | 2026-10-23 | Managing Member, Andivano LLC | Section 7a after the follow-up to the 2026-10-23 access review: the non-administrative desktop account was disabled and the ufw host firewall was enabled (inbound denied by default; SSH, the overlay network's WireGuard port, and the overlay interface allowed). The attack-surface statement is corrected: mDNS discovery, disabled on 2026-08-05, was found running again alongside two other wildcard-bound UDP sockets; the firewall has no rule admitting them from a public address. The supporting record is evidence/2026-10-23-quarterly-access-review.md. |
| 1.19 | 2026-10-26 | Managing Member, Andivano LLC | Adds Section 13a, a business continuity and disaster recovery plan, ahead of the eBay connection: a recovery point objective of 24 hours, with a failed copy reported by the watchdog after 26 hours; a recovery time objective of 48 hours on a new server, provided the operator workstation is available; what depends on that workstation, including unlocking the volume after a reboot, and what survives its loss together with the server; what is copied and where; the numbered steps to restore the production server, each with its check; and restore tests before the eBay production keys are issued and then at least once a quarter, the nearest no later than 2027-01-25. The host files that existed only on the production server (units, scripts, reverse-proxy configuration, and the SSH, firewall, failed-authentication jail, kernel and journal-retention settings) are now kept in the repository (infra/vps/host/), and the restore steps reinstall the host controls of Sections 4, 7 and 8 from them. Section 6 records the encrypted copy of the production secrets file in a password-protected keyring on the operator workstation, refreshed by the operator after every change and compared with the server's file by SHA-256 every quarter. Sections 3, 5, 6, 11, and 12 add the eBay connection: its data is classified as Confidential and eBay refresh tokens as Restricted; the refresh token is encrypted at the application layer and the seller's eBay user ID is kept only as an HMAC-SHA256 fingerprint; database backups contain no eBay connection data; an eBay notice that an account was closed or deleted erases the token and the fingerprint at once in every connection of that seller, the fingerprint of the deleted account stays in a technical register for at most 48 hours, and eBay connection data is also deleted on request and with the Taxller account, as the Privacy Policy of 2026-10-26 states; eBay is recorded as a data source under the seller's own authorization, not a subprocessor. |
Appendix A: Amazon SP-API Data Protection Policy Cross-Reference
Provided for reviewer convenience. "Applicability" reflects whether the cited control is general (applies to all SP-API developers) or scoped to the PII-Additional section of the policy — Taxller requests zero buyer PII (Section 3), so PII-Additional controls are noted as such even where Taxller elects to meet them anyway.
| DPP topic | Applicability | Taxller control | Reference |
|---|---|---|---|
| Encryption in transit (≥ TLS 1.2) | General | Section 5 | Guidance to address key security controls |
| Encryption at rest for PII (AES-128/256, RSA-2048+) | PII-Additional | Section 5 (AES-256 for documents, backups, and application-layer encryption of seller tokens; the database, the secrets file and the local backups sit on a LUKS2-encrypted volume whose key is not held on the host, verified by a restore test; SSE-KMS under a customer-managed key for the Section 7a report archives) | Protecting SP-API applications — data encryption |
| Credential/API key encryption & annual rotation | General | Section 6 | Guidance to address key security controls |
| MFA and account lockout (≤ 10 attempts) | General | Section 4 | Guidance to address key security controls |
| Password policy (≥ 12 chars, complexity, history, expiration) | General | Section 4 (14-char minimum for administrative access; 90-day expiry and MFA for console sign-in, with the programmatic exception stated in Section 4; 12-char minimum, four classes, breach check, 10-password history and 365-day maximum age for Taxller accounts; MFA required to connect an Amazon account) | Guidance to address key security controls |
| Quarterly access review; 24-hour termination removal | General | Section 4 | Guidance to address key security controls |
| Network protection (firewalls, segmentation, IDS/IPS, AV) | General | Section 7 | Guidance for network protection in SP-API |
| Log retention ≥ 12 months; bi-weekly/SIEM review; PII exclusion | General | Section 8 | Protecting SP-API applications — logging and monitoring |
| Vulnerability scans (30 days), pentest (annual), code scan pre-release | PII-Additional | Section 9 | Vulnerability management |
| Amazon incident notification (security@amazon.com, 24 hours) | General | Section 13 | Protecting SP-API applications — incident response |