Access, indexing, and passwords
Every share carries two independent settings:
- Access — one rung on an ordered ladder:
restricted<view<comment<suggest. This is who, holding the URL, can do what. Default:comment. - Indexed — a boolean.
false(default) means hidden: reachable only by its link, never listed, never crawled.truemeans public: listed on /discover, enumerated insitemap-shares.xml, crawlable.
A share can also have a password, but only when it is hidden and link-reachable — access above restricted, indexed off. That's the one state where a password is the only gate.
There used to be a three-tier visibility column (public / unlisted / members) and a separate link_permission. Both are gone. One ladder plus one flag replaced them.
The access ladder
restricted
The link grants nothing. The share renders only for people with an explicit grant:
- Admins of the share's owner org.
- Project members (
vieweroreditor) of the share's project — cross-org collaborators included. - Per-share editors (
share_members). - Org-wide viewers (
org_viewers).
Everyone else — anonymous visitors and signed-in users with no grant — gets a 404, not a 403. We don't leak that the share exists.
Pick restricted when the URL leaking would be the problem. To let someone in, use the invite flow or add them on the share settings page — see invites and doc-level roles.
view
Anyone with the link can read it. Nothing more — no comments, no reactions, no suggestions.
comment (default)
Anyone with the link can read. Signed-in users can also comment and react.
suggest
Read + comment + react, plus signed-in users can submit suggested edits. A suggestion lands as a pending version the owner approves or rejects — see version history.
Anonymous visitors only ever get read, at every rung. Commenting, reacting, and suggesting always require a signed-in account, so a recipient without a Google account signs in with a magic link first.
The indexed flag
indexed is orthogonal to the ladder — it controls listing and crawling, never who can read.
indexed = false (default) |
indexed = true |
|
|---|---|---|
| Reachable by URL | yes (per the access rung) | yes (per the access rung) |
X-Robots-Tag / robots meta |
noindex, nofollow |
none — crawlable |
| Listed on /discover | no | yes, if eligible (below) |
In sitemap-shares.xml |
no | yes, if eligible |
restricted shares are never indexed — the server forces indexed to false whenever access is restricted, on every write path.
Hidden is not private. noindex is a request to well-behaved crawlers, not enforcement. The URL is still public: anyone you send it to can read it, and a scraper that ignores robots directives will too. Treat a hidden share like an unlisted document, not a secret one. For real gating, use restricted, or add a password.
Passwords
A password is valid only on a share that is hidden (indexed = false) and link-reachable (access above restricted). The server rejects the other two combinations with a 400 before any write:
- Password on an indexed share →
indexed shares cannot have a password. A share that's public and searchable can't also be password-walled. - Password on a restricted share →
restricted shares cannot have a password. Membership is already the gate; a password adds nothing.
Consequently, flipping a password-protected share to restricted or to indexed clears the password. That's a destructive step, so it needs an explicit confirmation: --force on the CLI, ?force=1 on the API, the "Clear the existing password" checkbox in the dashboard. Without it you get a 400 telling you to pass force.
People who already hold a grant — the owner, org admins, project members, share editors, org viewers — read straight through a password-gated share without being prompted. The password gates link-only viewers.
Setting a password
Web: open the share's actions menu (⋯) on the dashboard and pick Set password / Change password. An empty value clears it.
CLI:
anchorify password set my-share
# prompts on TTY (no echo); reads stdin when piped
anchorify password set my-share --password "ramen-tornado-12"
anchorify password clear my-share
Setting access
Web
Share settings (/<org>/<project>/<slug>/settings) is the full control. Under General access you pick:
RestrictedorAnyone with the link, and when it's the latter, the rung (view / comment / suggest).- List publicly & allow search indexing — the
indexedcheckbox. It only applies to link-reachable shares. - Clear the existing password if the new access requires it — shown when a password is set.
The dashboard row menu (⋯) also carries three quick flips — Make public, Make unlisted, Make restricted — for the common cases. "Public" means indexed, "unlisted" means hidden; both keep the current rung. Finer control over the rung lives on the settings page.
The badge in every share list reads Restricted, Link · <rung>, or Public · <rung>, so the two settings are always visible at a glance.
CLI
anchorify access <slug-or-id> restricted|view|comment|suggest [--index|--no-index] [--force]
anchorify access my-share view # anyone with the link can read
anchorify access my-share comment --index # link + comments, listed publicly
anchorify access my-share restricted # only people you add
anchorify access my-share comment --index --force # also clears the password
--no-index is the default. --index and --no-index are mutually exclusive. restricted normalizes to not-indexed regardless of the flags.
At publish time (and on update, and for folder uploads) the same two knobs are flags:
anchorify report.md --slug q3-report --access view
anchorify notes.md --access suggest --index
anchorify update ./report.md --access restricted
anchorify upload-folder ./deliverables --access restricted
New shares default to --access comment --no-index.
The pre-unification tier flags and the old tier / link-permission subcommands were removed with the unified model. They aren't silently ignored — passing one exits 1 with an error pointing at anchorify access, so an old script fails loudly instead of publishing at the wrong access level.
API
curl -sX POST 'https://anchorify.io/api/v1/shares/k3p9x2af/access' \
-H "authorization: Bearer $ANCHORIFY_TOKEN" \
-H 'content-type: application/json' \
-d '{"access":"comment","indexed":true}'
{ "access": "comment", "indexed": true }
Add ?force=1 to clear a password the new state doesn't allow; the response then carries "password_cleared": true. A no-op returns "unchanged": true. A non-owner gets 404 (no existence leak). A blocked index transition gets 403 with "error": "index_forbidden" — see below. Full shapes in the API reference.
access and indexed are also accepted on the publish/update body (POST /, POST /api/v1/shares/...), so an agent can set them at creation time.
Downloads
Separately from who can read a share, the owner controls whether it can be taken away as a file. Every share allows downloads by default; turn it off on the share settings page, or:
anchorify downloads my-share off
With downloads off, /download and the ?raw=1 raw-file URL both 404, the toolbar's Download control and PDF export disappear, blob shares (images, PDFs, other binaries) lose their download CTA, and the CSV grid loses its Export button. The document still renders at its URL.
Two things worth being clear about:
- It is friction, not protection. The reader can still select the text, copy it, print the page, or read the source. If the content shouldn't reach someone, that's an access decision — set the share to
restricted— not a download one. - It is independent of the password gate. A password-protected share with downloads off still 404s on
/downloadfor a visitor who has entered the password correctly.
Download counts on the analytics page are retained when you turn the toggle off — it changes what happens next, not the record of what already happened.
Discovery and moderation
Making a share indexed opts it into a public surface, so there's a floor under it.
What actually gets listed
An indexed share appears on /discover and in sitemap-shares.xml only if it also has moderation_status = 'ok', access above restricted, no password, isn't deleted, and clears a small quality floor (real content — 20+ characters or an uploaded blob — and a derivable title). An indexed share that misses one of those still renders at its URL and is still crawlable; it just isn't listed.
The index gate
Becoming indexed is gated to keep the discovery surface clean. The gate fires only on a transition to indexed (publishing with --index, or flipping a hidden share public) — editing an already-indexed share is never re-gated.
- Pro orgs bypass the gate.
- Otherwise your account must be verified (signed up with Google) or older than 24 hours (
INDEX_MIN_ACCOUNT_AGE_MS). Magic-link signups are the cheap path for a spammer, so they age in. - And your org must be under 10 newly-created indexed shares in the trailing hour (
INDEX_MAX_NEW_PER_HOUR).
A blocked transition returns 403 index_forbidden with a plain-English reason. The share is still published and live at its link — only the public listing is held back. Retry the flip once you're verified or the window has passed.
Report and takedown
Share pages show a Report this page link in the footer for visitors who can't manage the share (owners and admins get the manage affordances instead, and full-bleed surfaces like decks and PDFs have no footer to put it in). It posts to /<org>/<project>/<slug>/report with an optional reason, and is rate-limited per IP; a repeat report from the same hashed IP is a no-op.
The first report against a clean share flips it from ok to flagged, which drops it out of /discover and the sitemap pending operator review. A flagged share still renders normally at its URL.
An operator can set a share to blocked, which is a takedown: the public render 404s regardless of indexed, and so does its report page. The owner still sees the share in their dashboard, badged blocked.
Automated malware/phishing scanning of public shares is not in place yet — moderation is reactive today.
See also
- Doc-level roles — org admins, project members, share editors, org viewers: who has a grant independent of the link.
- Invites — how to give someone a grant on a
restrictedshare. - API reference — exact request/response shapes and error codes.
- Command-line — every subcommand and flag.