Files Bridge
How an agent's Home kept in a bucket is reached from its sandbox, and
the storage credential the bridge holds, both in link-store-contract.
Every bridge speaks link-bridge's calls
(Bridges).
A storage credential
A bridge that reads and writes a cloud's storage for the agent is
handed a credential, never the cloud's own sign-in
(link_store_contract::authority::StoreSecret): {"token", "expires", "refresh_url", "refresh_token", "headroom_bytes"?}, an access token
sent as Bearer, when it ends (Unix seconds), where and with what to get
the next one, and, optionally, how many bytes it may still add.
Its refresh
link_store_contract::authority::Held refreshes the token with OAuth's own
refresh (RFC 6749, section 6: POST refresh_url, form-encoded,
grant_type=refresh_token&refresh_token=<grant>, answered
{"access_token", "expires_in", "headroom_bytes"?}) once two thirds of
its life have passed.
Where it refreshes
Over HTTPS, or HTTP only to this machine's loopback (127.0.0.1,
::1, localhost, by the address's parsed host), never following a
redirect.
Its room
It takes each answer's headroom_bytes as the room left. A write that
would pass it is refused before anything is sent (Held::reserve). A
refresh answered 400 or 401 ends the credential: every call after it
fails.
The files bridge
The files bridge (link_store_contract::files) serves an agent's Home
kept as objects in a bucket.
Its halves
Its client is the files-client feature of this crate (Link file's
bridge command, Link memory's serve-many); its server half (serve,
Homes, DirStore, and Crypt, rclone's crypt format) is the
files-bridge feature, for whatever serves it, so neither tool builds
it. files is both.
Who serves it
No part of Link serves the files bridge or runs lnk-file-tool bridge,
nor binds an agent's Home to lnk-link-memory serve-many through it: a
machine that runs agents only while they answer, with Home in a bucket,
does.
A team's folder
A read, write or list may name a team, <name> (a team of the
agent's own owner's, by the name its sandbox file's
[teams.<team>] gives it) or <account>/<name> (another
account's). A name never holds a / and an owner is an account's, so
the two forms never meet.
Reached at each call
It then reaches that team's folder instead of Home, as the server's
Homes::team gives it at that very call, never what was true when the
agent was bound, so an agent taken off a team, or a team renamed or
removed, is refused at its next call.
What it reads and writes
It reads the folders of it its grant writes or reads, writes only those
it writes (. for all of it), each from the version read, and lists
only what it reaches. Each write is told to the server
(Homes::team_changed), which keeps the team's memory current.
Its index
An index-get, index-put, index-list or index-delete naming a
team reaches the index kept beside that team's folder, in the folder's
storage, the team's memory's. Since the index tells what's anywhere in
the folder, it's read only by a member granted all of it (., read or
written), and written or deleted only by one writing all of it that the
server lets keep it (TeamFolder::keeps_index, as whoever pays for it
says), only as the index's own objects (<engine>/manifest.json and
its segments), within TEAM_INDEX_MAX. InTeam is the caller's side, a store named as
Home's is.
One check
Every call naming a team passes one check of the member's grant
(team_allows) before anything of the folder is reached. A call's
unknown field is refused, never ignored.