Back to the profile

Behind the site

How this site is built

This page explains how this site is put together and what it does with your data. A profile that talks about security and compliance ought to hold up to its own standards, so the details are here for anyone who wants to check.

The stack

This site is built with Astro and published as plain static files. Each page is generated ahead of time, so there is no database behind the pages. The scripts it does use are small, and they load only from this site's own domain.

The content, the data and the design are kept in separate layers, and a check in the project enforces the boundaries. The look of the site can change without touching a word of what it says.

Security headers

Every page is sent with the headers below. The web server's configuration is generated from the same file, and this page prints the values straight from that file, so what you see here is what is set.

The Content-Security-Policy is the strict one. It allows scripts, styles, images and fonts from this site only, and it allows nothing inline. A build check fails if any page carries an inline script or style, which is why the policy needs no exceptions.

The proxy that handles HTTPS in front of this site is configured to add Strict-Transport-Security, so it does not appear in the list.

Response headers sent with every page
HeaderValue
Content-Security-Policydefault-src 'none'; script-src 'self'; style-src 'self'; img-src 'self'; font-src 'self'; connect-src 'self'; manifest-src 'self'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; upgrade-insecure-requests; require-trusted-types-for 'script'; trusted-types 'none'
X-Content-Type-Optionsnosniff
Referrer-Policystrict-origin-when-cross-origin
Permissions-Policycamera=(), microphone=(), geolocation=(), payment=(), usb=(), browsing-topics=()
Cross-Origin-Opener-Policysame-origin
Cross-Origin-Resource-Policysame-origin
Cross-Origin-Embedder-Policyrequire-corp
X-Frame-OptionsDENY

Signed commits and checks

The commits for this site are signed with an SSH key. A signature ties a change to the key that made it.

The project has one command, npm run check. It runs a type check, a check on how the code layers import each other and a check that images carry no hidden metadata, then builds the site, then runs end-to-end browser tests, an accessibility scan, a link check, the voice and honesty check and the security.txt expiry check.

Software bill of materials

A software bill of materials lists the packages a piece of software is made from. This site publishes one in the CycloneDX format, generated from the project's lockfile with npm every time the site is built.

It lists the whole toolchain, because the build tools are what produce the files you receive. Packages that run in your browser are marked as required. Build and test tools are marked as excluded, which means they are used to make the site but never sent to you.

None of the packages in it run in your browser, because the pages use no third-party code. All of them are build and test tools.

Software bill of materials (CycloneDX JSON)

Privacy

This site sets no cookies and uses no third-party scripts, fonts or trackers. Everything on a page comes from this site's own domain.

Like any web server, the one behind this site keeps an ordinary access log: your IP address, your browser string, the page and the time.

Visits are counted with a self-hosted analytics tool that runs on the server hosting this site, not with a third-party service. It sets no cookies and does not follow you from site to site.

My email address is not written into any page. It is stored in a scrambled form and put together in your browser when you use the link, which stops simple scrapers but not every bot. The resume PDF carries no phone number, no email address and no street address.

Accessibility and motion

The pages are written to be used with a keyboard and a screen reader. There is a skip link, the headings follow the outline of the page, and the interactive parts are ordinary links, buttons and details elements.

The site uses one light color scheme, and the automated scan below checks its text contrast against WCAG AA. If your system asks for reduced motion, the animations are switched off and each page shows its final state straight away. Without JavaScript the content still reads in full, and only the email link needs it, which says so.

Every page is scanned with axe, an automated accessibility checker, at phone, tablet and desktop widths, with the system set to light and to dark. Automated scans find only part of the problems, so if something does not work for you, please let me know through the contact section on the home page.

The voice and honesty check

A check in the project reads the text of every page, and of the resume PDF, and fails when something is wrong. It runs as part of npm run check.

It checks that the writing sounds like me. That means no stock phrases of the kind AI writing leans on, no em dashes, no exclamation marks, and none of the phrases I avoid.

It checks that nothing overstates my experience, using a list of claims I have said are not true. It also checks that nothing private slips out: phone numbers, salary figures, email addresses written in plain text, and locations finer than the state.

The facts on the site come from one file and are never copied by hand, so the page and the resume cannot disagree with each other.

Pages made for one company are written later, one at a time, so this check cannot read them when the site is built. When such a page is made, its text goes through the same generic rules: no phone numbers, email addresses or salary figures anywhere on it, and no em dashes or exclamation marks in the part about how my experience lines up. The company's mission is quoted in its own words. The checks against my private details run in my job-search tool before it sends the text.

Reporting a security problem

If you find a security problem with this site, please report it by email. The details follow RFC 9116 and are published at /.well-known/security.txt.

Describe what you found and how to reproduce it, and give the maintainer a reasonable time to fix it before you share it more widely. This is a personal site and has no bug bounty.

Resume as PDF