1. One-page summary
Our honest current state, as of 2026-07-08: horsenose is an early-stage product run by a solo operator. We do NOT hold SOC 2 or ISO 27001 today, and we have not yet had an external penetration test. This page describes what we do, what we hold, and what we do not yet have. We would rather tell you plainly where we stand than overstate it.
- Who we are. horsenose is software for running a riding school — scheduling lessons, tracking attendance and how riders paid, managing passes and gift vouchers, calculating instructor earnings, and giving a stable’s customers a view of their own bookings. It is operated by DF Daniel Fojcik, a Polish sole proprietorship (NIP 6472592229 / REGON 387798601, Marklowice), trading as Nose / horsenose.
- Our two roles. We are the data controller for our own account, analytics, and security data, and a data processor acting on each stable’s instructions for the rider/customer data that stable enters. The processor relationship is governed by our Data Processing Agreement (DPA). See “Compliance framing” below.
- What we hold. Account email and optional profile name/phone; invitation email addresses; the operational records a stable enters about its riders (names, contacts, lesson participation, passes/vouchers, payment-tracking labels, free-text notes); bcrypt-hashed schedule PINs; SHA-256-hashed invitation tokens. We hold no payment-card or bank data and no health data. Full inventory in “Data we hold” below.
- What protects it. TLS everywhere with HSTS preload; encryption at rest (AES-256); database-enforced row-level security isolating each stable; server-side session validation; step-up re-authentication for destructive and admin actions; a strict Content Security Policy; rate limiting and bot protection; and an append-only audit log. Full list in “Technical measures” below.
- Where it runs. Across more than one region, and we add regions as we grow — the current primary region for each provider is listed under “Infrastructure — who runs what, and where” below and can change as we expand. Today, most core processing is in the EEA (database, email, analytics, error monitoring, and the rate-limit store), with a few components already outside it (Cloudflare’s global edge; Google sign-in and parts of Stripe in the US; Dodo Payments globally). Every cross-region route is covered by an appropriate transfer mechanism — the EU-U.S. Data Privacy Framework, the EU Standard Contractual Clauses, the UK Addendum, or the equivalent an added region requires.
- What we do not yet have. No SOC 2, ISO 27001, external penetration test, or bug-bounty programme. If your procurement process requires SOC 2 today, we are not yet the right fit.
- How to reach us about security. Email support@horsenose.eu with `Security` in the subject line. See “Incident response (72-hour breach notification)” and “Responsible disclosure” below.
2. Data we hold
We collect the minimum needed to run the Service. The categories below are the personal data that touches horsenose.
| Category | What it is | Our role | Where it lives |
|---|---|---|---|
| Account identity | Sign-in email address; authentication metadata (passwordless — email magic link, or optional Google sign-in identifier). No passwords are stored. | Controller | Supabase Auth (EU) |
| Profile data | Display name; optional phone number; locale/timezone | Controller (account-holders) | Supabase (EU) |
| Invitation data | The email address a stable invites; the invitation is carried by a single-use token stored only as a SHA-256 hash (the raw token is never persisted) | Processor (on the stable’s behalf) | Supabase (EU) |
| Rider / operational data a stable enters | Rider and customer names and contacts; which lessons they were scheduled for and attended; passes and gift vouchers issued, redeemed, or refunded; payment-method labels (cash / pass / voucher / transfer) recording that a rider paid, plus a record of any online payment where the stable enables it (amount, method, status — never card data); one-way announcements (subject and body); free-text notes on passes, payments, and horses | Processor (the stable is the controller) | Supabase (EU) |
| Schedule PINs | Optional PIN protecting a stable’s public schedule, stored as a bcrypt hash (not reversible) | Processor | Supabase (EU) |
| Usage & technical data | IP address (rate limiting, abuse prevention, security); browser/OS/device; pages visited | Controller | Vercel logs (EU); Upstash counters; Cloudflare |
| Error/diagnostic data | Crash and error traces, with personal data scrubbed before send (see “Technical measures” below) | Controller | Sentry (EU data region) |
| Product analytics (consent-gated) | Pseudonymous identifier, events, pages, device/browser; approximate country/city is resolved from the IP address before the IP itself is discarded at ingestion (PostHog’s "Discard client IP data" setting) — loaded only if you accept the cookie banner | Controller | PostHog EU Cloud |
What we do not hold
- No payment-card or bank data. horsenose is never a party to a payment and never handles card data. Offline methods ("cash", "pass", "voucher", "transfer") are tracking labels a stable records — not transactions horsenose runs. For the stable’s subscription billing (Stripe for Polish stables, Dodo Payments as Merchant of Record for non-Polish stables) and for online rider payments where a stable enables them (Stripe, settling into the stable’s own account), the card data is handled entirely on the payment provider’s own checkout and never reaches us — so we remain out of scope for PCI DSS (see “Compliance framing” below).
- No identity documents or addresses. We do not collect home addresses, ID-document numbers, or government identifiers.
- No special-category (health) data. We do not intend to collect Article 9 GDPR data and the product is not designed to store it. Stables are instructed (in the DPA) not to enter special-category data into free-text fields. Notes about a horse are about an animal, not a person, and fall outside GDPR.
- No advertising profiles, retargeting identifiers, or cross-site tracking. No Meta/LinkedIn/X/TikTok pixels; no browser fingerprinting.
- No data sold, rented, or loaned to third parties.
- No training of AI/ML models on your data. We do not train, fine-tune, or evaluate any AI or machine-learning model on personal data drawn from horsenose. The `pgvector` extension is enabled in our Postgres for future internal-search use cases but is not, today, populated with any personal-data-derived embeddings.
3. Infrastructure — who runs what, and where
horsenose is a Next.js application hosted on Vercel, backed by a Supabase Postgres database, with a small set of specialised providers ("sub-processors") each handling a narrow slice. None has end-to-end access to everything. We run across more than one region and add regions as we grow, so we describe where things are today rather than promising a single permanent location: most core processing — the database, email, product analytics, and error monitoring — is in the EEA, while a few components already run outside it (Cloudflare’s global edge; optional Google sign-in and parts of Stripe in the US; Dodo Payments on a global Merchant-of-Record basis). The current primary region for each provider is in the table below and is kept current as it changes; every cross-region route is covered by an appropriate transfer mechanism (the EU-U.S. Data Privacy Framework, the Standard Contractual Clauses, the UK Addendum, or the equivalent an added region requires).
| Provider | Role | Region |
|---|---|---|
| Supabase Inc. | Application database, authentication, file storage | EU — eu-central-1 (Frankfurt) |
| Vercel Inc. | Hosting, serverless compute, cron | EU — fra1 primary; global edge network |
| Brevo (Sendinblue SAS) | Transactional + magic-link email | EU (France) |
| PostHog Inc. (consent-gated) | Product analytics | EU Cloud (eu.posthog.com) |
| Sentry (Functional Software, Inc.) | Error monitoring | EU (data storage region); configured for its EU region, with SCCs as a fallback for any incidental processing outside the EEA |
| Upstash, Inc. | Rate-limit counters + idempotency keys (IP-derived) | EU — Regional database in eu-central-1 (Frankfurt, AWS); no cross-region replication; configured for its EU region, with SCCs as a fallback for any incidental processing outside the EEA |
| Cloudflare, Inc. | Turnstile bot protection, DNS, CDN edge | Global edge (DPF + SCCs) |
| Google LLC (optional sign-in only) | Returns a persistent account identifier on Google sign-in | United States (EU-U.S. DPF + SCCs fallback) |
| Stripe Payments Europe, Ltd. | Subscription billing for Polish stables (PLN, horsenose is invoice issuer); and, for stables that enable it, processing of online rider payments into the stable’s own account via Stripe Connect (the stable is the merchant; horsenose is not in the funds flow) | EU + US |
| Dodo Payments (Merchant of Record) | Legal seller of the subscription for non-Polish stables (EUR/GBP/USD); issues the tax-compliant invoice + calculates/remits VAT/sales tax | Global (MoR) |
The canonical, always-current version of this table — with per-provider personal-data categories and transfer mechanisms — is maintained on the Sub-processors page; the Privacy Policy and the DPA link to the same source rather than keeping divergent copies.
4. Technical measures
These are the controls actually in place today. This is also the substance behind the DPA → “Confidentiality, security, and sub-processors”, which points here for our technical and organisational measures.
Network and transport
- TLS for all traffic, enforced by Vercel and Supabase. HSTS is set with `max-age=63072000; includeSubDomains; preload`.
- No mixed content — the Content Security Policy rejects `http://` resources.
Tenant isolation and authorisation
- Row-Level Security (RLS) scoped to each stable on every operational table, enforced in the database itself — one stable’s data cannot be read by another even if application code had a bug. This is the primary cross-tenant defence.
- Application-layer role gates (authenticated / stable-scoped / instructor-or-admin / super-admin) as defence-in-depth on top of RLS, never as the only line.
- Route-layer checks require an active session for protected paths and super-admin status for the admin surface.
Authentication
- Passwordless sign-in — email magic link (handled by Supabase Auth) or optional Google sign-in (OAuth). No passwords are stored.
- Server-side session validation on every protected request — the sign-in cookie alone is never trusted.
- Step-up re-authentication for destructive and administrative actions — a short-lived, separately-signed step-up cookie is required for operations such as account deletion, last-admin role changes, bulk deactivation, stable archival, and all super-admin writes; missing or expired step-up fails closed.
- The platform-admin surface returns 404 when no super-admin is configured, so its existence is not leaked.
Secrets and credential handling
- Schedule PINs are stored as bcrypt hashes; invitation tokens are stored as SHA-256 hashes — single-use, time-limited (7-day expiry), and email-bound; raw tokens are never persisted.
- The database service-role key is server-only — it is never bundled into client JavaScript; a build-time validator fails the build if a sensitive variable is mis-prefixed.
Input and output handling
- Schema validation at every server input boundary — client-side validation is treated as UX only; the server is the trust boundary.
- A strict Content Security Policy with a per-request nonce, plus a locked-down security-header set (`X-Content-Type-Options`, `X-Frame-Options` / `frame-ancestors`, `Referrer-Policy`, cross-origin isolation headers, and a restrictive `Permissions-Policy`).
- Automatic output escaping; user-authored content is plain text at this stage.
Abuse and bot protection
- Rate limiting on sign-in, sign-up, magic-link, invitation-accept, export/erasure, and other sensitive endpoints (per-email, per-IP, per-user, or per-stable depending on the action; each policy is fail-open or fail-closed by design).
- Cloudflare Turnstile bot protection on the sign-in form, sign-up form, magic-link request, invitation-accept page, and public-schedule PIN entry.
Data at rest and audit trail
- Encryption at rest via Supabase (AES-256).
- An append-only audit log records security-relevant events (authentication, role and membership changes, financial events, exports, deletions). It is always written and is distinct from operational telemetry.
- Error monitoring with personal-data scrubbing — before any error is sent to Sentry, a custom scrubber drops email addresses, phone numbers, message bodies, notes, and any field that looks like a token. What remains is technical context plus a pseudonymous user UUID, the stable identifier, the locale, and the name of the failing operation.
Backups and recovery
- Supabase provides automated daily backups (7-day retention at the current tier; longer retention is planned as the Service matures). Vercel retains prior deployments for near-instant rollback of a bad release.
5. Organisational measures
- Solo operator. horsenose is run by one person (Daniel Fojcik). There are no employees with production access at this time. If that changes — for example, a contractor with production access is onboarded — this page will be updated and active stables notified.
- Production data stays on managed infrastructure. Production database dumps are not stored on local machines; local development uses a separate database with synthetic data.
- Least privilege for service accounts. The database service-role key is scoped to server-side use only; browser database access uses a limited key behind row-level security.
- Secrets management. Secrets live in the hosting provider’s environment configuration and a gitignored local file — never committed to the repository. Production secrets are not copied to local machines.
- Provider-side access logging. Administrative actions on our providers are logged by those providers; we review them on an ad-hoc basis.
- Confidentiality. Personnel (currently the proprietor) are bound to confidentiality regarding personal data processed through the Service, as reflected in the DPA.
- Change discipline. Code changes pass a strict type, lint, and automated-test gate before deploy, and database migrations are applied to a staging environment before production.
6. Incident response (72-hour breach notification)
Monitoring. Errors flow to Sentry (with the personal-data scrubbing described in “Technical measures” above); request-level diagnostics are available in hosting logs; an uptime monitor and error-rate alerting are part of the hardening baseline. The append-only audit log provides a durable record of security-relevant events for investigation.
Our breach-notification commitment. If a personal-data breach occurs that is likely to result in a risk to the rights and freedoms of affected individuals, we will:
- Notify the competent supervisory authority — the President of UODO in Poland — without undue delay and, where feasible, within 72 hours of becoming aware of the breach (Article 33 GDPR).
- *Where the breach is likely to result in a high* risk to affected individuals, notify them without undue delay, describing the nature of the breach, the categories of data involved, the likely consequences, and the measures taken (Article 34 GDPR**).
- Where we act as a processor for a stable, notify that stable (the controller) without undue delay so it can meet its own Article 33/34 obligations to its riders.
This mirrors the Privacy Policy and the DPA. It states how we intend to implement an obligation the GDPR already imposes — it is not an additional contractual promise beyond GDPR. A formally documented incident-response runbook is on the roadmap; until then a one-person team responds ad hoc within the timelines above.
Contact. Non-urgent: support@horsenose.eu. Security (urgent): email support@horsenose.eu with `Security` in the subject line.
7. Compliance framing
GDPR (Regulation 2016/679). horsenose operates under a dual role: controller for the data whose purposes and means it determines (marketing-site visitors, the account/contact data of stable administrators and instructors, consent-gated product analytics, and security/abuse-prevention data), and processor for the rider/customer operational data a stable enters — there, the stable is the controller and horsenose processes on the stable’s documented instructions under the DPA (Article 28 GDPR). Sub-processors operate under Article 28 contracts (DPA + SCCs/DPF, the UK Addendum, or an equivalent mechanism where a transfer crosses regions) — see the Sub-processors page.
Children’s data. Riding schools regularly teach children, so horsenose knowingly processes minors’ data on a stable’s behalf (for example, a child entered as a lesson participant, often by a parent who is the stable’s customer). The stable is responsible for the lawful basis and any parental consent or authority required (Article 8 GDPR); horsenose minimises what is held about a child and does not target or market to children directly. See the Privacy Policy → “Children’s privacy”.
Data-subject rights are supported, including self-service access/portability via a JSON export at /account/export and erasure via /account/delete (a 30-day reversible grace period and step-up re-authentication apply; on erasure we strip direct identifiers rather than hard-delete — pseudonymisation under Art. 4(5) GDPR, not full anonymisation under Recital 26; see the retention table in the Privacy Policy → “How long we keep data” for the field-level detail). For rider data the controller is the stable, so a rider exercises rights against their stable and horsenose assists as processor.
PCI DSS — not applicable to horsenose. We do not handle, store, or transmit card data. For the stable’s subscription billing, the card-data path is carried entirely by the payment provider on its hosted checkout — Stripe (payment processor) for Polish stables, with horsenose as merchant, and Dodo Payments as Merchant of Record for non-Polish stables. For online rider payments, where a stable enables them, the card, wallet, or BLIK data is carried entirely by Stripe (via Stripe Connect) and settles into the stable’s own Stripe account — the stable is the merchant and Stripe is the PCI-compliant processor, while horsenose only relays instructions and never receives card data. In every case horsenose never receives card data and remains out of PCI scope.
EU AI Act — not applicable. horsenose is an operations tool for riding schools; it does not train, develop, or deploy AI models, and no component uses machine-learning or generative AI to process personal data. The `pgvector` Postgres extension is enabled for possible future internal-search use cases but is not populated with personal-data-derived embeddings today; if that changes, we will publish an EU AI Act position and a "no training on personal data" commitment before the feature ships.
ePrivacy / cookies. Optional analytics (PostHog) load only on consent; strictly-necessary cookies are exempt under Article 5(3) of the ePrivacy Directive. See the Cookie Policy.
8. Responsible disclosure
If you believe you have found a security vulnerability in horsenose:
- Email [support@horsenose.eu](mailto:support@horsenose.eu) with `Security` in the subject line. (A dedicated `security@` address and a PGP key are planned.)
- Include enough detail to reproduce the issue.
- Give us a reasonable period to investigate and remediate before any public disclosure.
What you can expect from us:
- An acknowledgement and an initial assessment as soon as reasonably practicable. horsenose is a solo-operated service and cannot guarantee a same-day reply; we will not let a credible report sit unattended.
- Status updates at reasonable intervals while the issue is being triaged or fixed.
- Credit in any post-fix disclosure, if you would like it (optional).
What we cannot yet offer: we do not pay monetary bug bounties at this stage. We will say so clearly if and when a bounty programme becomes available.
Scope and safe harbour. Good-faith security research that follows this policy, stays within your own accounts, avoids degrading the Service for others, and does not access data other than your own will not be treated as a violation of our Acceptable Use Policy or Terms of Service. Do not attempt to access another stable’s or another rider’s data, and do not run automated scraping or denial-of-service testing against the Service.
9. Change log
| Date | Change |
|---|---|
| 2026-07-08 | Replaced session-replay claims with plain analytics-only language; converted numeric section cites to heading-name cites; aligned Sentry/Upstash transfer-mechanism wording with the Sub-processors page and the DPA. |
| 2026-07-02 | Subscription billing reconciled as live (Stripe for Polish stables; Dodo Payments as Merchant of Record for non-Polish stables); Upstash recorded as Regional EU-only (Frankfurt) throughout. |
| 2026-05-23 | Initial publication. |