// minio's object-store seat (novox/hq ADR 0468 §3, §8): the holder of `object-store`, serving `link`. A party that // needs to put a document into a bucket, or get one out, asks for one short link and moves the bytes over HTTP // itself; no document ever travels on the bus. // // The link is signed with the bucket's link key (issue 1594), which only reads and writes that bucket's objects, // never with the root account. Who may have a link is judged here, at each call, from the grant file the mesh // delivered to minio: the bucket's consumer, and whoever its `shares` name for that method. // // stdout is the MCP channel; what this module says, it says on stderr. package main import ( "context" "fmt" mesh "git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner" "os" "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient" stdio "git.novox.be/novox/mesh-sdk/go" "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" "git.novox.be/novox/mesh-sdk/go/views" ) // Words the manifest gives this bundle (modules/minio/module.json). const ( ConfigWord = "OBJECT_STORE_CONFIG" // the store as the machine reaches it: files/object-store.json, rendered LinksWord = "MESH_MINIO_LINKS" // the directory of the link keys' secrets (issue 1594) ReceivesWord = "MESH_RECEIVES" // the grant file ) func main() { seats := &views.Reader{Module: "minio", Findings: meshconditionsclient.FindingWriter{State: stdio.State("findings")}, Acts: meshhandactsclient.Recorder{Ask: stdio.Ask}, Logf: func(f string, a ...any) { fmt.Fprintf(os.Stderr, "[object-store] "+f+"\n", a...) }} seats.Follow(assignerModule, mesh.StateSeatHolders, SeatHoldersTool) s, err := newServer(os.Getenv(ConfigWord), os.Getenv(LinksWord), os.Getenv(ReceivesWord), func() (map[string][]byte, error) { return seats.Values(assignerModule + "." + mesh.StateSeatHolders) }) if err != nil { fmt.Fprintf(os.Stderr, "[object-store] %v\n", err) os.Exit(1) } seats.Start(context.Background()) if err := stdio.Serve("", append(tools(s), seats.Tools("object_store")...)); err != nil { fmt.Fprintf(os.Stderr, "[object-store] %v\n", err) os.Exit(1) } } // SeatHoldersTool is the assigner's read tool of who holds which seat, which the manifest invokes (ADR 0615). // assignerModule is the holder of the seat mesh-module-assigner whose seat-holders view this module follows: the one name // of it here, the same as its manifest's `consumes` and `invokes` carry (the manifest test holds them equal). const assignerModule = "mesh-delivery-assigner" const SeatHoldersTool = assignerModule + ".assigner_read_seat_holders" func tools(s *server) []stdio.Tool { return []stdio.Tool{{ Name: "object-store.link", Description: "A signed link to one object of a bucket, for one method, that lives at most ten minutes: the caller " + "moves the bytes over HTTP to it and never over the bus. Allowed to the bucket's own consumer and to whoever the " + "consumer's shares name for the method; the link is signed with a key that reaches that bucket's objects only.", Input: map[string]any{ "bucket": map[string]any{"type": "string", "description": "the bucket"}, "key": map[string]any{"type": "string", "description": "the object's key"}, "method": map[string]any{"type": "string", "description": "get to read the object, put to write it"}, "seconds": map[string]any{"type": "integer", "description": "how long the link lives, 1 to 600 (default 300)"}, }, Run: func(args map[string]any) (any, error) { return s.link(stdio.CallerOf(args), args) }, }} }