Access and sharing - Spacefast Docs

Access and sharing

Make a Space public, hand out scoped share links or a password, invite people, and revoke any of it.

After this page you can decide who opens a Space, hand out a link or a password scoped to part of it, and take any of that access back.

Access is a list, not a switch

A Space has no public or private flag. Access is a set of additive grants, each one naming an audience, a set of capabilities, the paths it covers, and which published target it applies to. A visitor is admitted when at least one grant matches. Removing every grant makes a Space private, because nothing admits anyone.

That model is why a Space can be public at /docs/** and closed everywhere else, and why revoking a share link takes effect on the next request rather than at the next publish.

The dashboard puts the three common shapes behind one control, and the CLI and API let you write any grant you want.

Audience Who it admits
public Anyone on the web
team Every member of the owning team
person One invited person, by email
link Whoever holds a share link
password Whoever knows a password
machine Whatever holds a bearer token
external An identity from a connected SSO or signer connection

Roles

A role is a named bundle of capabilities. Every grant carries one.

Role Can
viewer View pages
commenter View, read comments, write comments
editor The above, plus publish
manager The above, plus manage access

Share links and passwords are forwardable secrets, so they cap at viewer or commenter. Neither can be given manage.

In the dashboard

Open the Space and go to Access. The page header reads “Decide who can open this space.”

The General access card holds a segmented control with three options:

Option What it does
Private “Only people listed below can open it.”
Share link “The share link is the key. Anyone who has it can open it, no account needed.”
Public “Anyone on the web can open it.”

A second control, What visitors can do, sets the role that option grants. Everything else on the page is a card of its own: People, Share link, Password, Machine credentials, Access requests, Path rules, and SSO and identity. Anything more specific than the three-way control lives under the Advanced disclosure, and a Space with path-scoped rules shows the hint “Some paths have their own rules. See Advanced.”

Make a Space public

sf share grant --to public --role viewer --path '/**' --space my-site

Scope it instead of opening everything:

sf share grant --to public --role viewer --path '/docs/**' --exclude '/docs/internal/**' --space my-site

--to team does the same for the owning team. Patterns use * for one segment and ** for zero or more. A grant takes up to 100 include patterns and 100 excludes.

A public grant cannot carry publish or manage capabilities.

Share links

A share link is a durable URL that opens exactly the paths you scoped it to, with no account needed. The secret rides in the query string, so the link is the page:

https://my-site.view.fast/docs?__=sfl_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

One request returns that document. There is no redirect and no interstitial, so curl, an agent, and a browser all get the same page.

Create one

sf share link create \
  --space my-site \
  --name "Client review" \
  --landing /docs \
  --path '/docs/**' \
  --path '/assets/**' \
  --exclude '/docs/internal/**' \
  --role commenter \
  --expires 7d
Flag Default What it does
--name required The name shown in the links list
--landing / The clean route the link opens at. It has to be inside the link’s paths
--path /** An included pattern. Repeat for disjoint subtrees
--exclude none An excluded pattern, local to this link
--role commenter viewer or commenter
--target live live, all-versions, version:<id>, or branch:<name>
--not-before none Do not admit anyone before this timestamp
--expires never A duration such as 30m, 24h, 7d
--max-uses unlimited Successful opens before the link stops working, 1 to 1,000,000
--require-verified-email off Admit only visitors whose session has a verified email
--network none An allowed IP address or CIDR. Repeatable
--country / --exclude-country none Allowed or blocked ISO country codes
--exclude-user-agent none Block user agents containing this text

In the dashboard, the Share link card’s Create share link button opens a sheet with the same fields, labelled Name, What link holders can do, What the link opens, Opens at, Paths, Starts, Expires, Maximum opens, and a Require a verified email toggle.

List, copy, revoke

sf share link ls --space my-site
sf share link copy lnk_xxxxxxxx --space my-site --show-secret
sf share link revoke lnk_xxxxxxxx --space my-site

List reads never carry the secret. The URL is returned only to callers who may manage the Space’s access, and --show-secret is what prints it in a non-interactive shell.

Revoking drops the grant in the same write, so every outstanding copy of the URL stops working on the next request. The dashboard confirms with “Anyone using this link will immediately lose access.”

sf share link edit changes a link’s scope, role, target and constraints without rotating its URL, so a link you already sent can be narrowed rather than replaced.

A Space that has not been claimed yet may keep up to 50 active links, and further creates return anonymous_share_link_limit.

Passwords

A password is a separate audience with its own scope, not a lock on the whole Space. Several named passwords can coexist, each covering different paths.

sf share password create \
  --space my-site \
  --name "Beta testers" \
  --path '/**' \
  --role viewer \
  --password-from-stdin

Pass the value on stdin, or through SPACEFAST_SHARE_PASSWORD. It never goes into sf.jsonc. The verifier is Argon2id.

sf share password ls --space my-site
sf share password rotate pwd_xxxxxxxx --space my-site --password-from-stdin
sf share password revoke pwd_xxxxxxxx --space my-site

Rotating keeps the grant and its scope, and immediately signs out sessions that used the old password. Revoking removes the grant, so those sessions lose access too.

The dashboard’s Password card carries Set password, Change and Remove, with Expires, Paths and What password holders can do under Password options. It manages one password; the card’s own footnote points at the CLI and API for more.

Inviting people

sf share people invite person@example.com --space my-site --role commenter --scope /docs
sf share people ls --space my-site
sf share people remove person@example.com --space my-site

--scope defaults to / and is repeatable, so one invitation can grant the same role on several subtrees. --target picks what they get, defaulting to live.

In the dashboard, the People card takes an email, a What they can do role, and a What they get access to scope. Pending rows show Invitation pending with Resend and Remove actions.

A person can hold up to 32 scoped grants on one Space, so one collaborator can have different roles on different subtrees.

Machine credentials

For a script or a job, issue a bearer token rather than sharing a link:

sf share token create --space my-site --name "Nightly export" --path '/exports/**'
sf share token ls --space my-site
sf share token rotate mch_xxxxxxxx --space my-site
sf share token revoke mch_xxxxxxxx --space my-site

The token is shown once, right after creation. The dashboard says it plainly: “Copy it now. It won’t be shown again.” Rotating keeps the grant and its scope and invalidates the old token immediately.

Access requests

A visitor who lands on a Space they cannot open can ask for access. Requests show up in the Access requests card and in the CLI:

sf share request ls --space my-site
sf share request approve arq_xxxxxxxx --space my-site
sf share request deny arq_xxxxxxxx --space my-site

Approving invites the requester to the path they asked about.

What a visitor sees

On a public Space, the page loads. No access code runs at all.

With a share link, the link is the page. The token is redeemed before anything is read from disk, so the first request returns the document. The response is never stored in any cache, and it carries Referrer-Policy: no-referrer so the secret does not leak through the referrer header on outbound clicks.

On a protected Space with no proof, the request answers 403 with the Space’s access page and Cache-Control: private, no-store. The page offers whichever lanes you configured: a password box, an email code, a request-access form, or a sign-in with a Spacefast account.

Signing in sends the visitor to Spacefast, then back. The path they originally asked for is carried through the round trip, so they land on the page they wanted rather than the homepage.

Submitting a password posts it from the same origin, checks it against the platform rather than anything on the box, and on success sets the visitor’s session cookie and sends a 303 back to where they were. Passwords are capped at 1024 bytes. Failures come back as rate limited, invalid password, or exchange unavailable.

A visitor session is idle-expiring after 7 days and absolutely expiring after 30 days.

Two behaviors are worth knowing because they look like bugs and are not. A rewrite cannot widen access: both the URL the visitor asked for and the path it rewrote to have to be admitted. And a directory listing on a protected Space silently omits the rows that visitor cannot reach, rather than showing them and challenging.

Revoking everything at once

sf access logout-all --space my-site

This ends every active visitor session on the Space, whatever admitted them: share link, password, private open, or signed-in account. It takes effect immediately, without a republish. Grants themselves are untouched, so anyone still holding a valid link or password can open the Space again on their next visit. Revoke the grant when you want the credential itself dead.

Defaults for new Spaces

A team decides what its new Spaces start as. In the dashboard, open team settings and go to Access, headed “Choose how new spaces on this team start.”

Preset New Spaces start with
private No grant at all
team A grant admitting the owning team to view and comment on everything
public A grant admitting the whole web to view and comment on everything

The default is team. Changing it applies only to Spaces created after the change.

Last updated on September 5, 2026.