Security

Markland is in public beta and operated by a single developer (). This page describes the current security posture — honest about what is implemented, and explicit about what is not yet.

Authentication

Humans sign in with magic-link email — no passwords are stored. Sign-in links are signed with a server secret and expire 15 minutes after issue. The link is sent only to the email address on the request, and the session it creates is bound to a separate signed cookie. (We do not currently track per-token consumption server-side, so a captured link can be used within its 15-minute window before it expires — that gap is on the post-beta hardening list.) AI agents authenticate with scoped bearer tokens minted from a logged-in user account. Tokens are hashed at rest; only the bearer plaintext is shown once at mint time. You can revoke any token individually from settings, and all token issuance is recorded in an append-only audit log.

Document access

Documents default to private. Sharing is per-document, per-principal — not "anyone with the link." Each doc carries an explicit list of grants (user emails, agent IDs, single-use invite tokens) that the owner controls. The viewer code denies-as-NotFound when a caller has no grant, so a 404 from /d/{token} never reveals whether a doc exists. Public docs (opt-in only) do receive a stable share token; everything else stays scoped.

Concurrency & integrity

Updates take an if_version argument; concurrent writers see a clean ConflictError rather than silently clobbering each other. Every revision is stored in an append-only revision log so you can see what changed, when, and by whom (or which agent).

Transport & headers

All traffic is HTTPS. Responses carry HSTS, a strict Content-Security-Policy, X-Frame-Options DENY, X-Content-Type-Options nosniff, Referrer-Policy strict-origin-when-cross-origin, and a restrictive Permissions-Policy. Non-marketing paths additionally return X-Robots-Tag: noindex, nofollow so private surfaces don’t leak into search results.

Data handling

Documents and grants are stored in SQLite on the application server. Markland does not sell your data, share it with advertisers, or train AI models on it. See /privacy for what is and isn’t stored, and how to delete it.

Where the data lives

The application runs on Fly.io in the iad region (US-East, Ashburn VA) until the canonical domain cutover; the SQLite database lives on the same machine’s persistent volume. The underlying volume storage is encrypted at rest by the host platform; Markland additionally hashes bearer tokens and magic-link codes before they ever touch disk, so a snapshot of the database does not yield usable credentials. Host region and provider may change after general availability — this page will be updated when they do.

Analytics

We use Umami for aggregate pageview counts. Umami is privacy-first — it sets no cookies, doesn’t track individuals across sites, and does not retain IP addresses. We use it to understand which pages are useful and where readers come from. The script is not loaded on admin pages.

Reporting issues

A dedicated security contact will be published here once markland.dev is live. Until then: reply to any Markland email you’ve received and the message reaches a human who reads everything. Please include a description of the issue, reproduction steps if you have them, and an estimate of severity. Reports are not bug-bountied at this stage but they are read and acted on quickly.