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.mddirectly 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.
- Apache / LiteSpeed — OwnShip automatically writes an
.htaccessrule denying direct access to those four files. Nothing to do. - Nginx —
.htaccessis ignored. Add this to yourserver { }block:location ~* /_(site\.ini|order\.txt|header\.(md|html)|footer\.(md|html))$ { deny all; } location ~ /\.(?!well-known) { deny all; }
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.