This page sets out cloro’s commitment to security. It documents the technical and organisational
controls we operate, organised around the SOC 2 Trust Services Criteria so that
security reviewers can map it directly onto their own questionnaires.
We are a small team and we have written this page to be verifiable rather than
flattering. Controls we operate are described in the present tense. Controls we
do not yet have are listed explicitly in
what we don’t have yet. If a reviewer needs a
control that appears in that section, tell us — we would rather discuss the
gap than have you discover it three weeks into a procurement cycle.
Entity. Cloro Incorporation Ltd., 168 St. Christoph Street, VLT 1467,
Valletta, Malta.
Security contact. [email protected]
Data protection contact. Ricardo Batista — reachable through our
contact form under “Legal, privacy, or security”.
Compliance status
We state this plainly rather than implying more than we hold.
| Framework | Status |
|---|
| GDPR | Aligned. DPA available, incorporating the EU Standard Contractual Clauses (2021/914). |
| SOC 2 Type I | Not certified. Currently evaluating auditors and compliance platforms. |
| SOC 2 Type II | Not certified. |
| ISO 27001 | Not certified. |
| Independent penetration test | Not yet performed. |
The controls below are in place today and are described accurately. They have
not been examined by an independent auditor, and we do not claim otherwise.
Control environment and personnel
SOC 2 CC1
- cloro is a small, fully remote company. Security is owned by Ricardo
Batista, CEO, who is accountable for the controls on this page.
- All employees and contractors are bound by written confidentiality and
intellectual property agreements executed before they receive any access.
- Contractors with production access are held to the same access controls,
agreements, and offboarding process as employees.
- Because we are fully remote, we operate no offices containing customer data.
All production data resides in our infrastructure providers’ facilities, under
their physical security programmes. Those providers hold the independent
certifications we do not yet hold ourselves:
- DigitalOcean maintains SOC 2 Type II and SOC 3 Type II attestations
issued by Schellman & Company, CSA STAR Level 1, and PCI-DSS SAQ-A
validation. Its data centre facilities hold ISO 27001, ISO 9001, ISO 14001,
ISO 22301, SOC 1 Type II, and SOC 2 Type II.
- Hetzner is certified to ISO/IEC 27001:2022 by SOCOTEC Certification
Deutschland GmbH, covering all of its hosting services and data centres,
including the Nuremberg and Falkenstein facilities we use.
Access control
SOC 2 CC6
Internal access
- Multi-factor authentication is enforced across every internal system that
can reach customer data or production infrastructure: GitHub, DigitalOcean,
Doppler, Clerk, Stripe, and Google Workspace.
- Credentials are held in a company-wide password manager with MFA enforced.
Shared plaintext credentials are not used for production systems.
- Production database access is limited to the engineering team. Access is
granted by role on the team, not by default on hire.
- Access is reviewed every three months. Each review covers internal systems
and production datastores, and revokes access that is no longer required.
- Offboarding follows a documented checklist. Access to all systems is revoked
within one week of departure.
- Production networks are reachable only over our private Tailscale
network. Staff reach the databases, the analytics hosts and the Kubernetes
clusters only from devices on our tailnet. Tailnet lock is on, so a new device
must be signed by an administrator before it can connect. Access is granted by
role group, so each person reaches only the systems their role needs.
- Company laptops run macOS with full-disk encryption and automatic screen lock
enabled. We do not centrally manage devices (no MDM or EDR). A personal or
mobile device can reach production only after an administrator signs it into
the tailnet.
Secrets management
- Application secrets are stored in Doppler, one project per service, and synced
into Kubernetes secrets by the Doppler operator. No secret values are committed
to source control, and the previous hand-maintained secret manifests have been
retired.
- Each service receives only the environment variables it requires.
Customer-facing access
- Authentication is handled by Clerk. Dashboard users sign in with a
one-time code sent to their verified email address, or with their Google
account. We do not offer password sign-in, so there is no cloro password to
guess, reuse or leak. A second factor is not yet enforced.
- Tenant isolation is enforced server-side on every request. A request must
carry both a valid session and an active membership record for the
organisation it targets; requests failing either check are rejected before
reaching any business logic. API keys are bound to a single organisation, so a
key issued to one organisation cannot read another’s data.
- Roles are managed through Clerk’s organisation model and are recorded
against each membership. Each member is an admin or a member. Admins manage
the organisation’s members. Both roles have the same access to the
organisation’s API keys, usage and data. Custom roles are not available.
Free accounts have one member; paid plans allow unlimited members.
- Verified domains. Organisations can verify ownership of an email domain
through Clerk, so colleagues joining from that domain land in the correct
organisation rather than creating parallel accounts.
- API key lifecycle. Keys can be deactivated and given an expiry date, and
each key records a last-used timestamp so dormant credentials can be
identified and removed.
We do not currently offer SAML or OIDC single sign-on.
Encryption
SOC 2 CC6.1, CC6.7
- In transit. All public endpoints are HTTPS-only. Certificates are issued
by Let’s Encrypt and renewed automatically by cert-manager; plaintext HTTP is
redirected at the ingress, so an unencrypted request never reaches an
application. This covers
api.cloro.dev, dashboard.cloro.dev, and
cloro.dev.
- At rest. Our managed PostgreSQL database, block storage, and object
storage are encrypted at rest by our cloud provider.
- Credentials. API keys are never stored in recoverable form. We store a
SHA-256 hash of each key plus a short, non-sensitive prefix used only to
identify the key in the dashboard. A lost key cannot be recovered by us or by
anyone who obtains a copy of our database — it can only be rotated.
System operations
SOC 2 CC7
Vulnerability management
- Automated dependency vulnerability scanning is enabled on both application
repositories, and alerts are raised against the engineering team.
- Remediation targets: critical severity within 24 hours, high severity
within 3 days.
- Container images are rebuilt and redeployed on every merge to the default
branch, so dependency fixes reach production without a manual release step.
- Patching. We track the release notes and security advisories of the
platforms we run (Kubernetes, k3s, PostgreSQL, ClickHouse, Valkey and our
language runtimes) and plan our updates from them. DigitalOcean applies
updates to our managed PostgreSQL and Valkey clusters in their maintenance
windows.
Network security
- Our data services have no public endpoint. The managed PostgreSQL and
Valkey clusters accept connections only from our Kubernetes cluster
(DigitalOcean Trusted Sources). The ClickHouse hosts accept connections only
over our tailnet.
- The browser collection fleet is locked down at the host. Its servers
accept SSH only from two Tailscale bastions, password SSH is disabled, and
etcd accepts connections only from the control-plane nodes. Pod traffic
between nodes is encrypted with WireGuard.
- Web application protection. The website and the dashboard are served
through Cloudflare, which absorbs denial-of-service traffic at the edge. The
API is served through our own ingress, with HTTPS only, rate limits per API
key and per endpoint, a concurrency ceiling per organisation, and tenant
isolation checked on every request. We do not run a web application firewall
in front of the API.
Monitoring and logging
- Every API request is logged with a request ID, organisation, API key ID,
model, status code, latency, attempt count, and credits charged. This gives us
an auditable record of platform activity and gives you a reference to quote in
support conversations.
- Application logs and uptime checks run through Better Stack, with alerting on
error conditions and on availability degradation. Logs from customer-facing
services are held predominantly in EU regions (Germany) and retained for 7
days.
- Log sources. Better Stack holds the logs of the API, the dashboard API,
the async pipeline, scheduled jobs, the MCP server and the browser collection
fleet. The browser collection cluster also keeps its own logs, metrics and
traces (Loki, VictoriaMetrics, Jaeger).
- Infrastructure audit log. The Kubernetes API servers of the browser
collection cluster record who changed what, at metadata level (no request
bodies, so secrets never reach the log). The log is shipped to our log store.
- Scheduled jobs and backup tasks report a heartbeat on success. We alert on
the absence of a heartbeat, so a job that fails silently still pages us.
Monitoring built only on error events misses that failure mode.
Incident response
- We maintain a documented incident response plan and an on-call rotation with
defined escalation policies.
- Confirmed incidents affecting service availability are published to
status.cloro.dev, which is driven by measured
uptime and per-engine success telemetry rather than manual updates.
- Breach notification. Where we become aware of a personal data breach
affecting customer data, we notify affected customers without undue delay and
in no event later than 24 hours after becoming aware, as committed in Section
3(j) of our DPA.
Change management
SOC 2 CC8
- Changes are proposed as pull requests. Continuous integration runs
formatting, linting, type checking, tests, and a full build on every pull
request.
- Force-pushes to the default branch, and its deletion, are blocked on every
repository. Branch rules do not yet require an approving review or a passing
check before a merge.
- Pre-commit hooks run linting and formatting locally, so violations are caught
before they reach CI.
- We operate separate development and production environments. Production
credentials are not used for routine development.
- Deployment is automated: a merge to the default branch builds a container
image, publishes it to our registry, and rolls it out to the Kubernetes
cluster. Deploys are reproducible and tied to a specific commit.
- Infrastructure changes follow the same path. Kubernetes manifests and
Helm charts live in a version-controlled infrastructure repository. CI lints
the charts on every pull request and deploys them from the default branch.
Changes to the Tailscale access policy must pass the policy’s own tests before
they are saved.
Risk mitigation and vendor management
SOC 2 CC9
- Every subprocessor is bound by a data processing agreement. Transfers outside
the EEA are covered by the Standard Contractual Clauses incorporated into our
DPA.
- Additions to the subprocessor list are published at least 7 days before they
take effect and emailed to subscribers, as set out under
Subprocessors.
- We maintain a written disaster recovery runbook covering the failure of our
analytics infrastructure, including provisioning, restore, and cutover
procedures with defined recovery targets.
Availability
SOC 2 Availability criteria (A1)
Backups
| System | Backup | Retention |
|---|
| PostgreSQL (primary) | Continuous point-in-time recovery to any transaction | Rolling 7 days |
| PostgreSQL (secondary) | Independent daily logical dumps to separate object storage | 14 days |
| ClickHouse (analytics) | Full backup daily, incremental backups every 30 minutes, written off-host | ~3 days of incrementals plus supporting full backups |
Recovery objectives
| Scenario | Recovery time objective |
|---|
| Analytics host rebuild, storage volume intact | ~15 minutes |
| Full analytics restore from object storage | ~45 minutes |
Recovery point objective is effectively zero for PostgreSQL, which supports
transaction-level point-in-time recovery, and up to 30 minutes for analytics
data, matching the incremental backup interval.
Our infrastructure runs in a single cloud region. A full region outage is
outside our current recovery plan, and we say so rather than implying
multi-region resilience we do not operate.
Verified restores
A restore drill runs automatically every week. The most recent backup is
restored to a temporary database, validated against expected row counts, and
then discarded. The drill reports its own heartbeat, so a drill that stops
running raises an alert. A backup nobody has restored is a hypothesis, not a
backup.
Capacity
- Ingress capacity scales automatically with load.
- Each organisation has an enforced concurrency ceiling, protecting both the
platform and neighbouring tenants from a single runaway client.
- Requests are rate-limited per API key, per endpoint, with remaining quota
returned on every response via
X-RateLimit-* headers.
Confidentiality and data handling
SOC 2 Confidentiality criteria (C1)
What we process
cloro is a data collection API. The material we handle on your behalf is the
queries you submit, the results we return, and the operational telemetry around
those requests.
| Data | Retention |
|---|
| Synchronous request payloads and results | Not persisted after the response is returned |
| Asynchronous task records and results | Deleted 24 hours after the task reaches a completed or failed state |
| Result files (HTML pages, screenshots) | Deleted 2 days after they are created |
| Request telemetry (request ID, organisation, API key ID, query, model, status, latency, credits) | 6 months |
| Application logs from customer-facing services (API, dashboard, collection, async) | 7 days |
| Infrastructure and cluster logs | 30–90 days depending on source |
| Account, organisation, and billing records | Life of the account, then per our Privacy Policy |
Deleting an organisation cascades to its memberships, API keys, subscription,
and credit ledger records, and cancels its Stripe subscription. Deleting a user
removes their record and their contact in our email provider (Resend).
Staff access to customer data
Engineering staff can access stored request telemetry, which includes the query
text you submit. This access is used only for customer support and technical
troubleshooting. It is not used for analysis, benchmarking, or any commercial
purpose.
AI tools. Staff use AI assistants for troubleshooting. These tools are
configured so that our inputs are not used to train models. We do not have a
technical control that blocks consumer AI applications or browser extensions on
staff devices.
We do not train on your data
We do not use customer queries, results, or any customer data to train
machine learning models, and we do not sell or license customer data to third
parties. Your data is processed to deliver the service you requested, and for
no other purpose.
Deletion on request
On a verified deletion request we remove customer data from production systems
within 30 days. Data may persist in backups until those backups age out on
the retention schedule above, after which it is unrecoverable. Records held by
Stripe, HubSpot, PostHog and Pylon are not deleted automatically.
Privacy and data residency
SOC 2 Privacy criteria
- Our Privacy Policy sets out what personal information we collect
and why. Our DPA governs processing we carry out on customers’
behalf and incorporates the EU Standard Contractual Clauses.
- Data subject requests — access, correction, deletion, portability, objection —
can be raised through our contact form under “Legal, privacy,
or security”, and are handled within the statutory timeframes.
- Our data protection contact is Ricardo Batista, reached the same way.
Data residency. Our primary infrastructure — application services, the
PostgreSQL database, the analytics store, and all backups — runs in
DigitalOcean’s NYC3 region in the United States. Our browser collection
fleet runs on Hetzner infrastructure in Germany. Transfers of EU personal
data to the United States are covered by the Standard Contractual Clauses in our
DPA.
We do not currently offer an EU-only hosting option. If your organisation
requires EU data residency, contact us before you build on cloro so we can tell
you honestly whether we can meet the requirement.
Subprocessors
These are the third parties that process the data you send through the API on
our behalf: your queries, the results we return, and the request telemetry
around them. Each is bound by a data processing agreement. Transfers outside the
EEA are covered by the Standard Contractual Clauses incorporated into our
DPA.
The providers we use for our own account, billing, support and analytics data,
for which cloro is the controller, are not subprocessors. Our
Privacy Policy covers that data.
Change notification. We publish every change to this list in the
change log at least 7 days before a new subprocessor starts,
so you have time to object under Clause 9 of our DPA. Subscribe below
and we email you each change when we publish it.
| Subprocessor | Purpose | Data processed | Location |
|---|
| DigitalOcean | Cloud hosting, managed PostgreSQL, object storage | All application data and backups | United States |
| Hetzner | Browser collection fleet | Request payloads during collection | Finland, Germany |
| Worldstream | Browser collection fleet | Request payloads during collection | Netherlands |
| OVH | Browser collection fleet | Request payloads during collection | France |
| CloudAMQP | Job queue between the API and the collection fleet | Asynchronous requests and results, held until delivered | United States |
| Cloudflare | DNS, CDN, website hosting, and result file storage | Website request metadata; result files (HTML pages, screenshots), deleted after 2 days | Global edge network; result files in Western Europe |
| Snapshooter | Backup orchestration | PostgreSQL backup contents | United States |
| Better Stack | Logging, uptime monitoring, public status page | Application logs and request metadata | Germany, United States |
Change log
Each change is published here first. A new subprocessor starts no earlier than
its effective date.
| Published | Change | Effective |
|---|
| 25 September 2026 | Removed Amplemarket (signup enrichment) | 25 September 2026 |
| 26 October 2026 | Added Worldstream (browser collection fleet, Netherlands), in use since 25 September 2026 | 25 September 2026 |
| 26 October 2026 | Added OVH (browser collection fleet, France), in use since 16 October 2026 | 16 October 2026 |
| 26 October 2026 | Added CloudAMQP (job queue, United States), in use since 16 September 2025 | 16 September 2025 |
| 26 October 2026 | Cloudflare also stores result files (Western Europe), since 27 April 2026 | 27 April 2026 |
| 26 October 2026 | Corrected the Hetzner location to Finland and Germany | 26 October 2026 |
| 26 October 2026 | Removed Clerk, Stripe, Resend, Doppler, Mintlify, Pylon, PostHog, HubSpot, Google Ads and Reddit: they process our own account, billing, support, analytics or advertising data, not the data you send through the API | 26 October 2026 |
What we don’t have yet
Every trust page lists what a company has. This section lists what we do not,
because a reviewer will find out anyway and the discovery is worse than the
disclosure.
| Control | Status |
|---|
| SOC 2 Type I certification | Evaluating auditors and compliance platforms |
| ISO 27001 certification | Not started |
| Independent penetration test | Not yet performed |
| Formalised written policy set | Practices are operating but not yet documented as formal policies |
| Documented risk assessment programme | Not yet established |
| Formal security awareness training | Not yet established |
| Formal vendor security reviews | Vendor selection is not yet a documented review process |
| Cyber liability insurance | Not currently held |
| SAML / OIDC single sign-on | Not offered |
| Enforced MFA for dashboard users | Sign-in is by email one-time code or Google; a second factor is not enforced |
| Enforced code review | Pull requests are used; branch rules do not require an approving review or a passing check |
| Web application firewall on the API | Not in place; the website and dashboard are behind Cloudflare |
| Managed device fleet (MDM / EDR) | Endpoint encryption is enabled; central management is not. Production access needs a device signed into our tailnet |
| Multi-region failover | Single region; a full region outage is not covered |
We are working through this list. If one of these blocks a purchase, say so —
customer demand is how we prioritise it.
Reporting a vulnerability
If you believe you have found a security issue in cloro, email
[email protected] with enough detail to reproduce
it. We will acknowledge your report within 2 business days and keep you
updated as we investigate.
Please do not run automated scanning against production, degrade service for
other customers, access or modify data that isn’t yours, or perform social
engineering against our staff. We will not pursue legal action against
researchers who report issues in good faith and stay within those limits.
Our machine-readable policy is published at
/.well-known/security.txt per RFC 9116.
Security reviews and documentation
Send security questionnaires, vendor assessments, or DPA signature requests to
[email protected]. Tell us your deadline and we
will tell you honestly whether we can meet it.