diff --git a/cmd/olliesrv/internal/fs/doc.go b/cmd/olliesrv/internal/fs/doc.go index 9cd4d0d..baf23f3 100644 --- a/cmd/olliesrv/internal/fs/doc.go +++ b/cmd/olliesrv/internal/fs/doc.go @@ -68,17 +68,20 @@ // # Per-Agent File Ownership // // Agent directories are owned by their agent ID (UID) with group "agent" (GID). -// Permissions enforce isolation: +// Permissions enforce isolation while allowing frontend access: // -// - mode 0600: owner only (plan, ctl, fifo) — private to owning agent -// - mode 0640: owner rw, group r (cfg, name) — readable by other agents -// - mode 0440: owner r, group r (chat, log) — readable by other agents +// - mode 0660: owner + group rw (plan, ctl, fifo) — agent and frontend can access +// - mode 0640: owner rw, group r (cfg, name) — readable by frontend +// - mode 0440: owner r, group r (chat, log) — readable by frontend // - mode 0444: world readable (state, id) — non-sensitive, observable -// - mode 0220: owner+group write (prompt) — CLI and owning agent can submit +// - mode 0220: owner + group write (prompt) — CLI and agent can submit // // Admin clients (empty uname, "admin", or server owner) bypass permission checks. // This allows CLI tools and GUIs to manage all agents. // +// The "agent" group includes all agents and frontends, allowing inter-agent +// visibility while maintaining ownership-based isolation for sensitive operations. +// // # Blocking Reads // // Files like event block until their condition is met. diff --git a/cmd/olliesrv/internal/fs/spec.go b/cmd/olliesrv/internal/fs/spec.go index 48cb62d..80190e5 100644 --- a/cmd/olliesrv/internal/fs/spec.go +++ b/cmd/olliesrv/internal/fs/spec.go @@ -779,7 +779,7 @@ func buildAgentChildren(a *agent.Agent, s *session.Session) []virtfs.FsNodeDecl return nil }), ), - virtfs.FileNode("fifo", 0600, // owner only + virtfs.FileNode("fifo", 0660, // owner + group (frontend needs access) virtfs.Write(func(data []byte) error { input := strings.TrimSpace(string(data)) if input == "" { @@ -867,7 +867,7 @@ func buildAgentChildren(a *agent.Agent, s *session.Session) []virtfs.FsNodeDecl return data, nil }), ), - virtfs.FileNode("plan", 0600, // owner only + virtfs.FileNode("plan", 0660, // owner + group (frontend needs access) virtfs.Read(func() ([]byte, error) { return a.Plan(), nil }), @@ -949,7 +949,7 @@ func buildAgentChildren(a *agent.Agent, s *session.Session) []virtfs.FsNodeDecl } return out, nil }), - virtfs.FileNode("ctl", 0600, // owner only + virtfs.FileNode("ctl", 0660, // owner + group (frontend needs access) virtfs.Rdwr(func(_ context.Context, data []byte) ([]byte, error) { return dispatch([]ctlCmd{ {"kill", "destroy this agent", func(_ []string) ([]byte, error) {