OwnShip Guide

Keeping a Site Private

OwnShip has two separate things that sound like privacy but aren't the same. Hiding a file from the navigation is tidiness. Keeping a file from being read is access control. This page covers both, and where each one stops.

If you need hardened, iron-clad access control, use your host's built-in directory protection instead — OwnShip is a lightweight tool for shared hosting, and it doesn't pretend otherwise.

The password gate

Set password in _site.ini and the whole site sits behind a simple sign-in form. A correct entry starts an authenticated session that lasts for the browser session. Omit the key or leave it blank to disable.

password = mysecret

What it's good for. Keeping a site out of search engines and out of casual view — client previews, works in progress, a document you're circulating for review. The check runs server-side before any content is sent, so nothing leaks to someone who simply hasn't signed in.

What it isn't. It is not hardened against a determined attacker. It's a single shared password with no accounts and no lockout, and it's only as private as your connection — so serve the site over HTTPS. For access control around genuinely sensitive material, use your host's directory password feature (HTTP Basic auth) instead.

Under the hood it does the sensible things: a constant-time password comparison, a brief delay after a wrong guess, a fresh session ID on sign-in, and a session cookie marked HttpOnly and SameSite=Lax (plus Secure when you're on HTTPS).

Storing a hash instead of the password

By default the password sits in _site.ini in plain text. If you'd rather not keep the real password on the server at all, store a bcrypt or Argon2 hash instead. Generate one:

php -r 'echo password_hash("your-password", PASSWORD_DEFAULT);'

Paste the result as the password value. OwnShip detects a hash automatically and verifies against it. Plain text keeps working unchanged, so this is optional.

This matters most if you can't protect _site.ini at the server level — see below. With a hash, even a leaked _site.ini exposes no usable secret.

_ means hidden, not private

Files and folders whose names start with _ or . are hidden from the navigation and from search, and OwnShip refuses to render them through the page viewer. A request like ?page=_site.ini returns Not found on every server.

That is not the same as blocking them from the web. A browser can still request _data/notes.md directly by URL, because OwnShip never sees that request — the web server answers it first. Treat the _ prefix as tidiness, not security. If something must not be readable, don't put it in your web root at all.

Protecting system files

Blocking a direct request — someone typing /_site.ini into the address bar — is your web server's job, because it answers before OwnShip runs.

The files blocked from direct access are the four configuration and template files: _site.ini, _order.txt, _header.*, and _footer.*. Other _-prefixed files are not blocked, and must not be, for the reason given below.

Why this names files instead of blocking everything starting with _. Plenty of things you want hidden from the navigation still have to be served to the browser. Your theme files — _theme.css, _theme.js, and any _theme-NAME.css — are loaded as stylesheets and scripts, and an image in _images/ is fetched as an ordinary request whenever a page displays it. A blanket location ~ /_ { deny all; } would leave your site unstyled and your images broken.

If you can't edit your server config at all, store your password as a hash. That removes the only real secret from _site.ini, which is the file worth worrying about.