Public repositories on authenticated storage
Documentation/Run your server
Public repositories on authenticated storage4 min read

Public repositories on authenticated storage

On this page

An authenticated storage server can host private and public repositories on the same TLS endpoint. Repositories default to private. Public visibility permits anonymous discovery, metadata/history/branch reads, and download of accepted file content. It exposes every branch and all retained accepted history, including history accepted before the repository became public. It does not grant uploads, submits, repository creation, branch mutation, locks, workspace registration, operation outcomes, or administration.

Visibility belongs to shared auth policy, keyed by namespace and immutable repository ID. It is not versioned content in .scribe/config.toml. Changing it requires an auth administrator, independently of repository roles. Existing explicit roles and namespace administration continue to govern authenticated work.

Publish and restrict access

Use the administrator credential file and pending-state options described in the auth CLI reference; the credential file names the auth endpoint and its CA. For example:

sh
scribe-auth --admin-credential ./secrets/admin.credential visibility get personal/REPOSITORY_ID
scribe-auth --admin-credential ./secrets/admin.credential visibility set personal/REPOSITORY_ID public --expected-revision 0

Replace REPOSITORY_ID with the full ID from scribe repo list. get returns repository key, visibility, and revision. A missing policy is private at revision 0. Every successful set increments the revision. Use the latest returned revision to set private again. Concurrent updates with an old revision fail with base_mismatch; inspect the new policy before submitting a different intent.

Updates use the existing durable administrative ID, outcome, and audit mechanism. Retries retain the original outcome; reuse with a different intent is rejected. Auth can store policy before a repository exists, just as it can store grants.

Download and later contribute

sh
scribe --server tls://localhost:7557 --tls-ca ./ca.pem --anonymous repo list
scribe --server tls://localhost:7557 --tls-ca ./ca.pem --anonymous workspace create assets ./assets
cd assets
scribe --tls-ca ../ca.pem --anonymous sync

Without a credential file or saved session, TLS connections automatically use anonymous access: the client presents no certificate. --anonymous explicitly ignores saved sessions and SCRIBE_CREDENTIAL_FILE; it conflicts with --credential-file. Supplied invalid, disabled, or expired credentials fail; there is no automatic retry as anonymous. TLS trust is always required.

Anonymous working copies have only local workspace state. They do not allocate a persistent guest account or server-side workspace. Local edits remain protected by the ordinary recovery journal, opened-path deferral, and watermark rules.

After logging in with a user who has write permission, run scribe workspace register. This explicitly registers a fresh workspace identity, preserves files and opened edits, and allows subsequent submissions. Its identity is persisted before transmission, so interrupted registration can be retried. A saved anonymous ID is never evidence of authenticated ownership. Resolve pending operations and view/switch workflows before registration.

Enforcement, scale, and revocation

The storage authorization layer enforces both callers through AuthProvider. The gateway forwards a signed-in user's access certificate, which storage checks against the gateway's delegate grant, or an anonymous connection; it never substitutes its own credential. Its private inventory is not an authorization decision. See gateways and delegation.

Discovery visits at most 128 repository candidates per request and checks them in one bounded auth batch. Replies can be empty with a continuation. Secured cursors are opaque, connection-scoped, and replaced on each continuation; they do not reveal skipped private IDs. Finish a listing before interleaving other operations. CLI listing aggregates pages with a one-million-repository/page safety bound.

Storage shares a bounded 1,024-entry public-policy cache and coalesces concurrent misses for the same key. Decisions last at most 30 seconds, further limited by credential expiry. After expiry, an unavailable auth service denies new read admissions. Visibility changes take effect within the same bound; already admitted bounded requests can finish, and downloaded content cannot be recalled.

Anonymous connections are limited to half the configured connection capacity, and anonymous requests to half the smallest query/storage/transfer worker pool (with a minimum of one). Admission, including anonymous handshakes, happens before acquiring shared worker permits. Anonymous frame bodies can use at most 64 MiB of the shared 128 MiB request budget. Chunk requests use the ordinary bulk-transfer pool and existing size limits.

Public-only object reads expose accepted manifests. Chunk reads additionally name their manifest; storage verifies accepted membership and the chunk reference. One anonymous chunk request may make the server read at most 64 MiB of those witness manifests; a larger one is refused (a public chunk read may name at most 64 MiB of manifests at once; request fewer chunks). Uploaded or rejected objects do not become public merely by existing. Explicitly granted repository readers retain their existing object access. Acceptance records manifest membership in the same transaction as accepted history, including merges. doctor and verify check this index without repairing it.

The unreleased repository schema requires the accepted_manifests table; startup does not silently initialize missing indexes. Object bytes, IDs, and chunking fixtures are unchanged. See on-disk format and wire format for canonical encodings.

Source docs/public-repositories.mdSnapshot 2b8dcccb