The view: one read-only bus user for a page in a browser, composed like every other (hq research 036)
Research 036 names the gap (G1): no way for a browser to reach the bus. The bus module now listens over WebSocket (mesh-catalog, nats); this is who connects there. The view is a fixed principal (broker.KindView, user `view`) composed into the user list like every user once its credential is minted, and left out once it is forgotten: it subscribes the issue tracker's events (opened, moved, noted, linked), the controller's plan-moved and condition-raised/changed/cleared, and the delivery owner's transition and group; it publishes only the JetStream API requests a read-only watcher of the tracker's bucket (mesh-issues_issues) makes — STREAM.INFO, DIRECT.GET, CONSUMER.CREATE/INFO/ DELETE, flow control — answered in its own inbox; no reply, no tool, no event, no `$KV` write. `bus view-credential` mints and prints it once (hash kept, like a person's); `bus view-revoke` forgets it, real at the next composition. Tests: the composed grants are exactly these and a write grant of any shape fails; the view is composed only once minted; and against a real server read from the composed file over WebSocket, the view binds the bucket, reads a key, watches a put land, and is refused a put, a delete and an event, the bucket unchanged.
This commit is contained in:
@@ -67,6 +67,9 @@ type Records struct {
|
||||
Enrolling []string
|
||||
// People is each person's name against the tools they may invoke, `*` for an administrator.
|
||||
People map[string][]string
|
||||
// View says the mesh minted the view's credential (`bus view-credential`), so the one read-only
|
||||
// view principal is composed (KindView); forgotten, it is left out, like a person.
|
||||
View bool
|
||||
// Interchangeable is each module whose definition says its instances are the same anywhere
|
||||
// (ADR 0160), which decides whether the module's plain subject is issued to every instance.
|
||||
Interchangeable map[string]bool
|
||||
@@ -142,6 +145,9 @@ func Users(r Records) ([]Principal, error) {
|
||||
for _, person := range sortedNames(r.People) {
|
||||
out = append(out, Principal{Kind: KindPerson, Module: person, Invokes: r.People[person]})
|
||||
}
|
||||
if r.View {
|
||||
out = append(out, Principal{Kind: KindView})
|
||||
}
|
||||
|
||||
// Refused here rather than discovered by the server. Two users with one name is a file the
|
||||
// server reads as one of them, and which one depends on the order — so a module assigned to a
|
||||
|
||||
Reference in New Issue
Block a user