# Security · Onto
> Onto's security posture with a source for every claim: how API keys are stored, what's encrypted, what we don't claim, and how to report a vulnerability.

**Source:** /legal/security
**Extracted:** 2026-09-24T18:14:20.450Z

---
Security

## Every claim on this page _has a receipt._

Each line states a control and cites the file that implements it or the measurement that confirms it. The last section is the same list with nothing to cite: the things we don't have.

Written and current · checked 24 Sep 2026

Report a vulnerability

[founder@buildonto.dev](mailto:founder@buildonto.dev)

First response

Within one business day

Machine-readable

[security.txt](/.well-known/security.txt)

13

Controls, each with a source

6

Processors

6

Things we don't claim

Keys and access

### Everything that decides whether a request is yours.

1.  A Read API key is shown once, when it's made. Only its SHA-256 digest is stored, with the prefix every key shares (onto\_sk\_live), so it can't be recovered by us or by anyone with the database.
    
    _Implemented in_`onto-api/lib/auth.ts · hashKey()`
2.  Replacing a key revokes the old one on its next request. Every call looks the key up and needs it active; nothing caches that answer.
    
    _Implemented in_`onto-api/lib/auth.ts · status !== 'active'`
3.  Dashboard sign-in is Supabase Auth: GitHub, Google, or email and password. Supabase hashes the password; Onto's code passes it through and never stores it.
    
    _Implemented in_`onto-dashboard/src/app/(auth)/actions.ts`
4.  The MCP connector signs you in through Onto's own OAuth server. PKCE with S256 is required; access tokens last an hour, refresh tokens 30 days, and a refresh token is replaced every time it's used.
    
    _Implemented in_`onto-api/lib/mcp/oauth.ts · oauth-handlers.ts`
5.  The connector's calls to the API carry a signed token minted per user that expires after two minutes and is verified on arrival.
    
    _Implemented in_`onto-api/lib/connector-token.ts · HS256, 2m`
6.  Quota is counted per account per calendar month (UTC) and resets on the 1st. The free tier stops at 1,000 credits; it can't overspend.
    
    _Implemented in_`onto-api/lib/rate-limit.ts · TIER_LIMITS`

In transit and at rest

### Where your data goes, and what protects it there.

1.  TLS 1.3 with a valid certificate chain and HTTP/2 on buildonto.dev, app.buildonto.dev and api.buildonto.dev.
    
    _Measured_`openssl s_client · 24 Sep 2026`
2.  Records live in one Postgres database on Supabase. Vercel KV holds the short-lived rest: the hour's page cache, this month's quota counters, MCP sign-in grants, and the keyless reader's per-IP counts. There's no analytics warehouse.
    
    _Implemented in_`@supabase/supabase-js · @vercel/kv`
3.  A read's result is cached for one hour under a SHA-256 key of the engine version and the URL, then expires. It holds the public page, not your account data.
    
    _Implemented in_`onto-api/lib/cache.ts · TTL_SECONDS = 3600`
4.  Encryption at rest is Supabase's and Vercel's, under their own published controls. We don't add a second layer, and would rather say so than imply one.
    
    _Measured_`Provider-managed`

What we send to other sites

### Onto makes requests to other people's sites for you. This is how.

1.  The API's fetcher names itself Onto-Reader/1.0 and links to a page saying what it does. (The free scanner on buildonto.dev fetches as a browser and as GPTBot instead; the Onto-Reader page says so.)
    
    _Implemented in_`onto-api/lib/fetch-and-clean.ts · USER_AGENT`
2.  robots.txt is read before every fetch. A site-wide Disallow for GPTBot or \* stops it before the page is requested. If robots.txt can't be fetched, that's taken as allowed.
    
    _Implemented in_`onto-api/lib/fetch-and-clean.ts · checkRobots()`
3.  A read sends at most four requests, waits 15 seconds for the page, runs no JavaScript and keeps no cookies. It only visits more of a site when a customer asks it to map or batch one.
    
    _Implemented in_`onto-api/lib/fetch-and-clean.ts · crawl.ts`

Every request, and the robots.txt that actually stops it, is on [About Onto-Reader](/about-bot).

Processors

### Everyone who touches your data.

Read off the services the code actually calls. Checked 24 Sep 2026.

1.  [**Vercel**Their privacy policy](https://vercel.com/legal/privacy-policy) Hosting, and Vercel KV (run by Upstash) for short-lived dataEvery request in transit; page payloads cached for an hour; monthly quota counters; MCP sign-in grants; the keyless reader's per-IP counts; cookieless page analytics on buildonto.dev`next, @vercel/kv, @vercel/analytics`
2.  [**Supabase**Their privacy policy](https://supabase.com/privacy) The database, and dashboard sign-inAccount (email, name and company if you gave them), sign-in identity, API key digests, usage records per call, Serve visit records, pages your SDK uploads, reports you save`@supabase/supabase-js`
3.  [**Polar**Their privacy policy](https://polar.sh/legal/privacy) Billing and subscriptionsYour email, plan and purchases. Card details stay with Polar`@polar-sh/sdk`
4.  [**Resend**Their privacy policy](https://resend.com/legal/privacy-policy) EmailYour email and first name for the welcome email; your message, email and plan when you contact support`resend`
5.  [**Notion**Their privacy policy](https://www.notion.so/notion/Privacy-Policy) The old waitlistEmail addresses left on the waitlist before signup opened on 5 June 2026`@notionhq/client`
6.  [**Google Fonts**Their privacy policy](https://policies.google.com/privacy) Fonts on the reader pagesYour IP address and browser details when you open a page at md.buildonto.dev`fonts.googleapis.com`

What we don't claim

### The same list, with nothing to cite.

A vendor who won't say what they lack hasn't really told you what they have.

1.  SOC 2 Type II. Not attested, not in an observation window.
    
    _Evidence_`none`
2.  ISO 27001. Same.
    
    _Evidence_`none`
3.  A third-party penetration test. None commissioned yet.
    
    _Evidence_`none`
4.  A 24/7 on-call rotation. Onto is a small team in one timezone; response is best effort.
    
    _Evidence_`none`
5.  An uptime SLA. We haven't run long enough to have a number we'd sign.
    
    _Evidence_`none`
6.  A bug bounty. Reports get a reply and credit if you want it, not money.
    
    _Evidence_`none`

Disclosure

### Found something? Tell us directly.

**Email founder@buildonto.dev**With steps to reproduce. You'll hear back within one business day from someone who can fix it. We won't threaten you, and we'll credit you publicly if you want it.

**Please don't scan the API**Automated scanners against api.buildonto.dev mostly test the rate limiter, and the counters are shared. Tell us what you want to test instead.

[**Privacy**What we collect, how long we keep it, and how to have it deleted._Read it_](/legal/privacy)

Related

### How the fetcher behaves toward your site.

The outbound half of this page, in full: what it sends, who can trigger it, and the robots.txt that stops it.

[About Onto-Reader](/about-bot) [Privacy Policy](/legal/privacy)

---
## Structured Data (JSON-LD)
```json
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://buildonto.dev/#org",
      "name": "Onto",
      "url": "https://buildonto.dev",
      "logo": "https://buildonto.dev/icon.png",
      "sameAs": [
        "https://x.com/buildonto",
        "https://github.com/ravixalgorithm/ontosdk"
      ]
    },
    {
      "@type": "WebSite",
      "@id": "https://buildonto.dev/#site",
      "url": "https://buildonto.dev",
      "name": "Onto",
      "publisher": {
        "@id": "https://buildonto.dev/#org"
      }
    },
    {
      "@type": "SoftwareApplication",
      "name": "Onto",
      "applicationCategory": "DeveloperApplication",
      "operatingSystem": "Web",
      "url": "https://buildonto.dev",
      "description": "Onto serves AI agents clean Markdown from your own site, at the same URL, and shows you which agents came. Plus the AIO score, a Read API and an MCP server.",
      "publisher": {
        "@id": "https://buildonto.dev/#org"
      },
      "offers": {
        "@type": "Offer",
        "price": "0",
        "priceCurrency": "USD",
        "description": "Free tier: 1,000 credits / month"
      }
    }
  ]
}
```
