Detail — security

How this site is secured

This portfolio runs a live AI assistant that costs real money on every answer, so it’s built like a small production service. Here is what protects it, in plain language — and what doesn’t yet.

  1. Spending limits on the AI assistant

    Each visitor can ask up to 8 questions per 10 minutes, and the whole site has a daily cap of 200 answers. Both counters live in Upstash Redis, so they hold across every server instance. If the limiter can’t be reached, the assistant refuses to answer instead of letting requests through. Behind that sits a monthly spend limit on a dedicated Anthropic workspace.

  2. Inputs are capped and checked first

    Requests over 16 KB are rejected, each message is cut to 800 characters, only the last 8 turns are kept, and answers are capped at 500 tokens. Malformed requests are refused before they reach any limit or the model.

  3. Only this site can call the assistant

    The assistant’s endpoint accepts browser requests only from simonlaborde.com. Any other website gets a 403 and no permission to read the response.

  4. Prompt-injection tests

    Six probes try to override the instructions, extract the system prompt, swap the assistant’s persona, smuggle instructions in through pasted text and pressure it into sharing private details — plus one normal question to check it still answers. All six passed against the live site. The assistant has no tools, takes no actions and only sees this site’s public content; its answers are shown as plain text, never as HTML.

  5. Your questions and your privacy

    Questions are sent to Anthropic’s Claude API to generate an answer. This site doesn’t save conversations, and your IP address is held for up to 10 minutes for rate limiting. No cookies, no analytics.

  6. Security headers

    A Content Security Policy that only allows this site’s own scripts, styles, fonts and connections; HTTPS enforced with HSTS; no MIME sniffing; a strict referrer policy; camera, microphone, location and payment features switched off; and no other site can embed these pages in a frame.

    See the live report on securityheaders.com ↗

  7. No third-party requests

    Fonts are self-hosted, so neither building the site nor visiting it contacts Google Fonts or any other third party — and the Content Security Policy enforces it.

  8. Every change passes the same gates

    Each change is a pull request that must pass a lint, a production build, a browser smoke test, a dependency audit, a secret scan of the full git history (gitleaks) and CodeQL static analysis. The main branch is protected with no admin bypass — not even the owner can push to it directly. Dependabot proposes updates, and CI actions are pinned to exact commit hashes. The audit that set this up also caught a critical Next.js advisory in the deployed version (GHSA-vcvr-r3jv-pc5j); it was patched the same day.

  9. Personal data

    The public CV is generated without a phone number — the generator refuses to build it otherwise — and the git history was rewritten to remove the number from every past commit.

Known limitations

Report a vulnerability

Found a problem? Email simonrl865@gmail.com — the address is also in /.well-known/security.txt. Please don’t open a public issue for security problems.

Full threat model: SECURITY.md on GitHub ↗