Control who can visit
Keep a space private, then grant access to people, links, passwords, machines, or the public.
Claimed spaces start private with an owning-team Grant. A URL by itself identifies content. It does not grant access. To admit anyone else, you create a Grant for a person, a review link, a password, a machine, or the whole public internet.
Grants
Five dimensions define a Grant:
- Audience: Public, Team, Person, Link, Password, Machine, or an external identity.
- Paths: Exact or wildcard paths, with optional exclusions.
- Role:
viewer,commenter,editor, ormanager, each a named set of capabilities (page.view,comments.read,comments.write,content.publish,access.manage). - Target: Live, all versions, one version, or one branch.
- Constraints: Optional time, use-count, email, IP, country, or user-agent limits.
Access is additive. Spacefast allows a request when one active Grant matches every required dimension, and an exclusion applies only to its own Grant.
Let the owning team view a subtree:
sf share grant --to team --role viewer --path '/docs/**'
Make the whole live space public. To make immutable version URLs public
too, add --target all-versions:
sf share grant --to public --role viewer --path '/**'
Explain the effective result for one route and audience:
sf share check --as public --path /docs/start
sf share lists every active Grant and where it came from.
People and access requests
Invite a person to a scoped role:
sf share people invite person@example.com --role viewer --scope /docs
List, edit, or remove people:
sf share people ls
sf share people edit person@example.com --grant /docs=commenter
sf share people remove person@example.com
Visitors can request access from the private-space access page. List pending requests, then approve or deny:
sf share request ls
sf share request approve req_123
sf share request deny req_123
Approval creates a Person Grant. It does not make the space public. Responses do not reveal whether an unknown private space exists.
Links
A Link is a revocable browser credential backed by one Grant. It can cover multiple paths, allow comments, expire, limit uses, or target live content or versions.
sf share link create --name "Client review" --landing /proposal --path '/proposal/**' --exclude '/proposal/internal/**' --role commenter --expires 7d
List Links and copy a credential URL:
sf share link ls
sf share link copy lnk_123 --show-secret
Revoke a Link and every session it admitted:
sf share link revoke lnk_123
Passwords and machine credentials
Passwords can carry the viewer or commenter role without a user
account:
sf share password create --name "Launch review" --password-from-stdin --role commenter --path '/launch/**'
Rotate one:
sf share password rotate pwd_123 --password-from-stdin
Machine tokens are header-only bearer credentials that can also carry the
editor or manager role:
sf share token create --name "Docs publisher" --role editor --path '/docs/**'
Rotate a compromised token:
sf share token rotate mch_123 --show-secret
Treat password proofs, Link URLs, and machine tokens as secrets. CLI JSON
and non-interactive output mask them unless you explicitly use
--show-secret.
Script reads of a private space
sf fetch fetches private space content through the
same central exchange and host-only cookie flow as a browser. The path
defaults to /, and the required --output flag names the file that
receives the response body:
sf fetch /docs --output ./docs.html
For header-only bearer access, create a machine token instead.
External identity
Connect an OpenID Connect (OIDC) provider or a white-label Ed25519 signer, then create Grants for the external subjects it proves.
sf share identity create --type oidc --name "Company login" --issuer https://login.example.com --client-id your_client_id --client-secret your_client_secret
sf share identity grant --connection con_123 --subject user@example.com --name "Docs reviewer" --role commenter --path '/docs/**'
Connections are team-owned, not per-space. The API manages them under
/v1/teams/{teamId}/identity-connections, and external audience Grants on
any of the team’s spaces can reference the same connection.
Signer rotation can overlap old and new keys. Revoking a connection revokes its external Grants and admitted sessions.
Public paths in sf.jsonc
Make only assets public:
{
"access": {
"public": ["/assets/**", "/favicon.ico", "!/assets/private/**"],
},
}
Make the whole space public:
{ "access": "public" }
On an unclaimed space, this block is inert until the space is claimed.
Public responses are cacheable. Spacefast never stores private or credential-bearing responses in the public cache, and a change to access purges the affected entries.
URL types
| URL | Purpose |
|---|---|
| Live | Stable content address. Grants no access. |
| Open | Temporary author access. |
| Link | Visitor access backed by one revocable Grant. |
| Claim | Ownership recovery for an anonymous space. |
The three credential URLs work differently:
- Open links carry their secret in a URL fragment on the handoff
broker. The broker exchanges the secret for a short-lived, host-bound
handoff, and the serving host sets a
__Host-cookie before redirecting to the clean live URL. - Link URLs are served on the space’s own host as
https://<space-host>/<landing>?__=<token>, with no redirect and no interstitial page. - Claim links open the dashboard at
https://my.spacefast.com/claim#<key>.
The access page
A private page renders its access page on the space’s own domain. The page offers only the methods that the space’s Grants allow: Spacefast sign-in, company single sign-on (SSO), a password, or an invite request. If only one SSO lane exists, Spacefast can go straight to that provider.
Theme the page with the theme section of sf.jsonc, or, on a paid plan,
replace it with _pages/access.html. A custom access page must render
<sf-access-lanes>. For details, see Visitor pages.
Network constraints and logout
Network limits apply to one Grant. They do not deny access that another matching Grant allows.
sf share grant --to public --role viewer --path '/partner/**' --network 203.0.113.0/24 --country NL --exclude-user-agent bad-crawler
To invalidate every browser session without changing Grants:
sf access logout-all