SECURITY & DATA
Trust should be inspectable.
This site asks you to talk to an AI rather than read a portfolio. That puts the obligation on me: if I ask you to put something into a system I built, you should be able to see what happens to it.
So this page describes the system as it is: which services are involved, what crosses each boundary, what is kept and for how long, and what isn't done yet. It is also how I approach security in general, with this site as the worked example. Privacy is what's collected and why; security is how it's protected. They are kept apart below.
Last updated 2026-10-04
APPROACH
How I think about it
01
Trust should be inspectable
If I ask you to talk to a system I built, you should be able to see what it does with what you say. Reassurance is cheap; a description you can check is not. So this page names services, says what crosses each boundary, and lists what isn't done yet.
- One source for these facts, used by this page and by the summary AI assistants read (/llms.txt).
- Gaps are listed below, not left out.
02
Don't collect what you don't need
Data that is never collected can't leak, be misused or need deleting. The default is to not keep things, and to justify each exception.
- No accounts, no sign-in, no visitor database.
- The conversation lives in the page's memory and nowhere on the server.
- Analytics, if you allow it, records the kind of question you asked, worked out in your browser. Never the words.
- The contact form sends me an email. There is no stored copy on the site.
03
Keep the boundary on the server
Anything the browser holds, the visitor holds. Secrets, access decisions and anything private stay on the server, and the browser is told only the outcome.
- API keys are server-side environment variables, never shipped to the browser and never in source control.
- Gated material is checked on the server before a single byte is served. Hiding something in the interface is not treated as protection.
- Internal review tools answer only on my own machine in development, and return 404 everywhere else.
04
Fail closed
When something is missing or misconfigured, the safe outcome is that it stops working, not that it quietly opens.
- If the access passphrase is unset or is a placeholder, nothing unlocks.
- If the calendar can't be read, bookings close rather than risk a double booking.
- A storage credential with write access refuses to load in the deployed site at all.
05
Least privilege, scoped credentials
Each credential can do only the one job it exists for, so a leak of any one of them is bounded.
- Asset storage uses a read-only key in production. The write key is a separate credential that only an offline job holds.
- The calendar connection asks Google for free/busy and event creation only, not full calendar access.
06
Security is risk management, not a state
Nothing here is “secure” in the absolute. It's a set of decisions about which risks matter for a personal site that talks to an AI, what each control is actually for, and what remains open.
- Rate limits slow abuse down. They are described as friction, not as a wall.
- Known gaps have their own section, with what I intend to do about them.
AT A GLANCE
The short version
- What I collect
- What you choose to send: messages to the AI, a message through the contact form, or the name, email and note for a booked call. Analytics only if you accept it.
- What I don't
- No accounts, no visitor profiles, no stored conversations, no advertising or cross-site tracking, no session recording, no fingerprinting.
- Conversations
- Not stored by this site. Each message is processed by Google's Gemini to write the reply, and is gone from the page when you leave or press “Let it go”.
- Who processes AI requests
- Google, through the Gemini API.
- Where data goes
- Netlify (hosting and DNS), Google (Gemini for the AI; Workspace for my inbox; Calendar if you book; Analytics only if connected and you accept), and Resend (email delivery).
- Questions or reports
- The contact form on this site. Security reports: see Responsible disclosure below.
DATA FLOW
When you talk to the site
Your browserYour device
You type a message. The conversation so far is held in the page's memory only: not in cookies, local storage or the address bar.
leantonio.me, a Netlify serverless functionMy systems
Receives the whole conversation so far (up to 15 turns; your messages up to 4,000 characters each). It checks the shape and size, and applies a per-address rate limit held briefly in memory. No visitor identifier is attached and nothing is written to storage.
Google Gemini APIThird party
Receives the conversation, plus fixed instructions and my published writing and work. It doesn't receive your IP address, browser details or any identifier from this site. Google handles the request under its Gemini API terms.
Back to your browserYour device
The reply streams back and is shown. Any work it references is looked up from the site's own published record, not fetched from elsewhere.
AI AND YOUR DATA
Plain answers
Does the AI know who I am?
No. It knows what you type in this conversation and nothing else. The site sends no name, account, cookie, IP address or device information to it. If you tell it who you are, it knows that for this conversation only.
Do I see your conversation?
No. It isn't stored or logged, so there is nothing for me to read. The server keeps only error codes, never message content. I see something you wrote only if you send it to me: through the contact form, or the note on a call you book.
Is my conversation stored?
Not by this site. It exists in your open page and is gone when you reload, close the tab or press “Let it go”. Google processes each message to write the reply, and keeps API data under its own terms (next answer).
Is it used to train anything?
Not by me: nothing here learns from conversations. The site uses the paid tier of the Gemini API, under which Google says it doesn't use prompts or responses to improve its products. It logs them for a limited period, solely to detect misuse and for legal requirements.
Does my conversation become part of what the AI knows about you?
No. What it knows about me comes from fixed files published with the site: my writing, my work record and my public code summaries. Conversations are never written back into that.
Can another visitor see or be influenced by what I say?
No. Each request carries only its own conversation, and the server holds no shared conversation state. Nothing one visitor says reaches another visitor's replies.
Which AI provider processes my message?
Google, through the Gemini Developer API. The model is gemini-flash-lite-latest, Google's name for its current Flash-Lite model. That line is read from the live configuration, not typed in.
Should I enter confidential information?
No. Talk about your work in general terms. Leave out client names under NDA, personal data about other people, credentials, and anything you wouldn't send to a third-party AI service. If you want to discuss something confidential, write to me directly.
What happens with “Ask your own AI about me”?
It opens Claude, ChatGPT or Perplexity in a new tab with a prompt about me, including a short excerpt of our conversation (the most recent turns from both sides, trimmed to fit a link). That only happens when you choose it, and from then on it is between you and that service. “Copy the prompt” puts a longer version on your clipboard instead.
And when I book a call?
When you pick a time, the site asks Gemini to draft a short note from the conversation so far (both sides, the last 16 turns). The draft appears in the booking form for you to edit or clear. Only what's in the box when you press Book reaches me, along with your name, email and time zone.
PERSONALISATION
What the site notices, and forgets
The site adapts a little to what you're interested in. It is less than the word suggests, so here is all of it.
- Within a conversation
- The AI marks where the conversation has got to (for example, that you're weighing up a project), and the “Ask your own AI” label changes to match. This lives in the page's memory and ends with the conversation.
- On the evidence pages (/ask)
- The site notes up to six areas of interest from the page you arrived on, questions you ask there and essays you open. These are kept in your browser's session storage and cleared when you close the tab. They go to the server only as part of the request that answers your question, to choose which evidence to show, and are not stored there.
- Not observed
- Hover, scrolling, time on page, returning visits and anything across sessions or sites. Nothing is inferred about you between visits.
- To reset
- Close the tab, or press “Let it go” in the conversation.
INFRASTRUCTURE
The systems involved
Most of what sits around the site is Google: Gemini for the AI, Calendar and Meet for calls, Analytics if you allow it. Hosting is Netlify, and outgoing email is Resend. Fonts are bundled with the site rather than loaded from Google, and nothing else is loaded from anywhere else.
MY SYSTEMS
leantonio.me on Netlify
Static pages and serverless functions, built from Git. No visitor database. Secrets held in Netlify's environment.
Google: Gemini API
Each message you send
The conversation text, fixed instructions and my published material. No identifiers.
Google: Analytics 4
Not connected at the moment: nothing loads, and nothing asks
Page paths (without query strings), the kind of question asked, which buttons were used, and a GA cookie identifier. Google signals and ad personalisation are off.
Google: Calendar and Meet
When you book a call
For a booking: your name, email, time zone and note go into the event, and Google sends you the invitation. Otherwise only free/busy queries about my own calendar.
Resend
When you send a message
The message you wrote and the reply address in it. Resend keeps sent mail and delivery logs for a limited period under its own terms.
Google Workspace
When you write to me or book
Messages you send me through the site, booking notifications, and anything you reply to.
SECURITY
How it is protected
- Infrastructure
- Static pages and serverless functions on Netlify, built from this site's Git repository, with DNS on Netlify too. No servers of my own to patch, and no database holding visitor data.
- Encryption in transit
- HTTPS everywhere, with HSTS telling browsers never to use plain HTTP. Calls from the site to Google and Resend are also HTTPS.
- Secrets
- Keys live in Netlify's environment, read only by server code and never sent to the browser. Local copies are gitignored, and none has ever been committed.
- Access
- I'm the only person with access to production: the hosting, the code, the Google project behind the AI, email delivery and the domain. Every one of those accounts uses two-factor authentication.
- Browser hardening
- A Content Security Policy that allows scripts only from this site and, after consent, Google Analytics. The site can't be framed by others. Strict referrer policy, no MIME sniffing, and camera, microphone and location turned off.
- Input handling
- Every public endpoint checks the type and size of what it receives. Email is HTML-escaped before sending. The contact form turns away messages with too many links, empty messages, and form-filling bots (hidden field, minimum time).
- Abuse and cost
- Layered, cheapest first. Requests must come from the site's own pages. Each address gets a per-minute and per-hour limit. The whole site has a daily allowance of AI messages, kept as a single shared count with nothing about any visitor in it. And every reply is capped in length and tool use. The per-address limits live in each server's memory, so they slow abuse rather than stop it; the daily allowance is the hard stop.
- Prompt injection
- Assume someone will try to talk the AI into something, and limit what that could achieve. It has no secrets to give away: everything it draws on is public. Its tools only read the published record, and it can't change anything. Its earlier replies come back signed by the server, so nobody can put words in its mouth, and visitors can't forge the notes the site adds. In replies, links only work for this site and the domains in my record, and images aren't shown. It's instructed to stay on its subject and turn down unrelated work. None of this makes it impossible to get an odd answer out of it; it keeps an odd answer from becoming anything worse.
- Access-controlled material
- A passphrase, compared in constant time, sets an httpOnly, secure cookie for 12 hours. The server re-checks it on every gated request, and it fails closed when unset.
- Dependencies
- Versions are pinned by a lockfile, the dependency list is deliberately short, and the framework is on its current major version with no known advisories in production dependencies. There is no automated vulnerability scanning yet.
- Monitoring
- Errors are logged as status codes, never with message content. There is no third-party error tracking, session replay or uptime service.
- Deployment
- Every change goes through Git and deploys automatically from the production branch. Development runs locally with its own environment variables, and the review tools only exist there.
- Backups
- There is no visitor data to back up. The site is rebuilt from its Git repository.
KNOWN GAPS
What isn't done yet
No automated dependency or code scanning.
NEXT · Add Dependabot alerts and a CI audit step.
Per-address rate limits are held per server instance, not shared.
NEXT · Move them to a shared store. The site-wide daily allowance already is one.
The Content Security Policy still allows inline scripts.
NEXT · Move to nonce-based scripts.
No uptime or error alerting.
NEXT · A simple external uptime check.
THIRD PARTIES
Who else processes data
Hosting, CDN and serverless functions
RECEIVES · Every request, as with any web host: IP address, requested address, browser details. Function logs hold only status codes from this site and are kept for 7 days. Netlify also runs the domain's DNS.
Writes the AI's replies; drafts the note when you book a call
RECEIVES · The conversation text, fixed instructions and my published material. No identifiers.
Google: Analytics 4
Not connected at the moment: nothing loads, and nothing asks
How Google uses data ↗Counts visits and which parts of the site are used
RECEIVES · Page paths (without query strings), the kind of question asked, which buttons were used, and a GA cookie identifier. Google signals and ad personalisation are off.
Checks when I'm free; creates the event and Meet link for a booked call
RECEIVES · For a booking: your name, email, time zone and note go into the event, and Google sends you the invitation. Otherwise only free/busy queries about my own calendar.
Delivers email from the site to my inbox (and booking invitations in one mode)
RECEIVES · The message you wrote and the reply address in it. Resend keeps sent mail and delivery logs for a limited period under its own terms.
My inbox, mail@leantonio.me
RECEIVES · Messages you send me through the site, booking notifications, and anything you reply to.
RETENTION
What persists, and for how long
- Conversation
- Your open page only. Gone on reload, close or “Let it go”. Not kept by this site.
- Gemini API
- Paid tier: logged by Google for a limited period to detect misuse, not used to improve its products.
- Messages you send me
- In my Google Workspace inbox (mail@leantonio.me), like any other email, until I delete it.
- Booked calls
- The calendar event, with your name, email and note, stays in my calendar.
- Analytics
- None: analytics isn't connected at the moment.
- Rate limiting
- Your IP address, in server memory, for at most about an hour. Never written anywhere.
- Your browser
- Your analytics choice and theme (local storage, until you clear them); interest areas on /ask (session storage, until the tab closes); an access cookie for 12 hours, only if you use an access code.
- Hosting logs
- Netlify function logs, holding status codes and not what you wrote, for 7 days.
To ask what I hold about you, or to have it deleted, write to me through the contact form. In practice that means emails you sent and calendar events you booked: the site itself holds nothing else about you.
RESPONSIBLE DISCLOSURE
Found a problem?
If you find a security problem with this site, tell me through the contact form, starting the message with “Security”. Include what you found, how to reproduce it and what it affects. Please don't access other people's data, degrade the service or run automated scanners against it.
I'll reply, keep you informed while I fix it, and credit you if you'd like. There's no bug bounty: this is a personal site, and I won't pretend otherwise.
