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.