diff --git a/config/trustees.mjs b/config/trustees.mjs
new file mode 100644
index 00000000000..652f6bdf21e
--- /dev/null
+++ b/config/trustees.mjs
@@ -0,0 +1,35 @@
+/*
+ * This defines the FreeSewing web of trust
+ * See: https://FreeSewing.dev/reference/trust
+ */
+export const trustees = {
+ 1: {
+ x: 1306,
+ y: 319,
+ title: 'joost',
+ in: 'Antwerp',
+ },
+ 132: {
+ x: 457,
+ y: 345,
+ title: 'woutervdub',
+ in: 'Seattle',
+ },
+ 13050: {
+ x: 668,
+ y: 399,
+ title: 'karen',
+ in: 'Chicago',
+ },
+}
+
+/*
+ * These are the connections between the trustees
+ * See: https://FreeSewing.dev/reference/trust
+ */
+export const connections = [
+ [1, 132],
+ [1, 13050],
+]
+
+export const lastUpdate = '20240402'
diff --git a/markdown/dev/reference/trust/en.md b/markdown/dev/reference/trust/en.md
new file mode 100644
index 00000000000..a7315972fc5
--- /dev/null
+++ b/markdown/dev/reference/trust/en.md
@@ -0,0 +1,62 @@
+---
+title: Web of Trust
+---
+
+In the wake of [the March 2024 supply-chain attack on XZ
+Utils](https://www.wired.com/story/xz-backdoor-everything-you-need-to-know/) --
+which attempted to smuggle a backdoor into Linux distributions -- FreeSewing has
+taken steps to guard against the attack vector where a contributor gains trust
+over a long period of time, with the end goal to smuggle malicious code into the project.
+
+__Elevated permissions or access will only be granted to people who are in FreeSewing's web of trust__.
+
+We have established an initial web of trust (more on this below) and have
+revoked elevated permissions from all other contributors.
+
+
+
+##### Paranoia much?
+
+We appreciate that -- given to the nature of software FreeSewing provides -- the chances of a supply chain attack by an adversary willing to invest months or even years to gain our trust are vanishingly small.
+
+Still, we are a small part of the larger open source ecosystem, and we cannot foresee the ways in which others may end up using our software.
+In addition, we want to help normalize this approach, and help raise awareness of the risks involved in trusting pseudo-anonymous contributions.
+
+
+
+## Defining trust
+
+To understand what we mean by a _web of trust_, we need to keep in mind what we want to guard against.
+In other words, the web of trust should prevent:
+
+**Someone attempting to gain our trust -- possibly over a prolonged period of time -- to achieve a malicious goal.**
+
+Right from the start, you can see that this is impossible. There is no real way to know people's true intentions, so we cannot guard against that.
+However, if we assume people try to pull this off without giving up their real identity, we can instead just focus on identity instead.
+
+The FreeSewing community exists almost exclusively online.
+In contrast, **FreeSewing's web of trust is made up of people who know and have verified each others _real_ identities**.
+
+In other words, to gain elevated permissions or access in FreeSewing, we need to know who you are and where you live.
+
+## Joining the web of trust
+
+To join FreeSewing's web of trust, you should:
+
+- Be a contributor
+- Reach out to one of the current trustees
+- Meet up with them -- physically, in the real world -- and verify each other's identities.
+- Once the current trustee vouches for your identity, you can be added to the web of trust
+
+
+Being a trustee is a requirement to be granted elevated privileges. It ddoes not automatically grant them.
+
+
+## FreeSewing's web of trust
+
+
+
+## Trustees
+
+
+
diff --git a/sites/dev/components/web-of-trust.mjs b/sites/dev/components/web-of-trust.mjs
new file mode 100644
index 00000000000..cb4eb190860
--- /dev/null
+++ b/sites/dev/components/web-of-trust.mjs
@@ -0,0 +1,9512 @@
+// Dependencies
+import { trustees, connections, lastUpdate } from 'config/trustees.mjs'
+import { shortDate } from 'shared/utils.mjs'
+// Hooks
+import { useState, useContext } from 'react'
+// Context
+import { ModalContext } from 'shared/context/modal-context.mjs'
+import { PanZoomContext } from 'shared/components/workbench/pattern/pan-zoom-context.mjs'
+// Components
+import { Point } from '@freesewing/core'
+import { ModalWrapper } from 'shared/components/wrappers/modal.mjs'
+import { WebLink, linkClasses } from 'shared/components/link.mjs'
+import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch'
+import { UserIcon, MapMarkerIcon, FingerprintIcon, LinkIcon } from 'shared/components/icons.mjs'
+
+/**
+ * This displays the trustees as a table
+ */
+export const WebOfTrustTable = () => {
+ const { setModal } = useContext(ModalContext)
+
+ return (
+
+
+
+
User
+
Location
+
+
+
+ {Object.keys(trustees).map((id) => (
+
+
+
+
+
{trustees[id].in}
+
+ ))}
+
+
+ )
+}
+
+/**
+ * Helper method to draw a connection between two trustees on the map
+ *
+ * @param {object} from - An objectt with x and y coordinates
+ * @param {object} to - An objectt with x and y coordinates
+ * @return {string} pathString - The path string to draw the path
+ */
+const fromToPath = (from, to) => {
+ const p = {}
+ const angle = 35
+ const shift = 0.5
+ p.from = new Point(from.x, from.y)
+ p.to = new Point(to.x, to.y)
+ p.fromCp = p.from.shiftFractionTowards(p.to, shift).rotate(-1 * angle, p.from)
+ p.toCp = p.to.shiftFractionTowards(p.from, shift).rotate(angle, p.to)
+
+ return `M ${p.from.x},${p.from.y} C ${p.fromCp.x}, ${p.fromCp.y} ${p.toCp.x}, ${p.toCp.y} ${p.to.x}, ${p.to.y}`
+}
+
+/**
+ * This component shows the trustee details, typically loaded in a modal window
+ *
+ * @param {number} props.id - The id (FreeSewing user id) of the trustee
+ */
+const Details = ({ id }) => (
+ <>
+