trust

package
v1.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 15, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package trust holds the rules about folders the user vouches for.

Everything here is a pure function of a path, the home directory, and the config-tree guard: no live site, no session manager, no app mutex, and nothing that reads the declared list. That is deliberate. These rules are what stands between a page and a durable write grant over a tree, so they should be readable and testable without standing up an HTTP server, a port, and a temp home first.

The declared list itself stays in package main, next to the sites it anchors: adding and removing a folder has to move listeners and registrations, so it is app work, not policy.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IdentityOK

func IdentityOK(path, pinned string) bool

IdentityOK reports whether the directory at path is still provably the one that was declared. An empty pin (a platform without fingerprints) leaves the path as the entry's whole identity.

Types

type Policy

type Policy struct {
	Home string
	// Guard reports whether dir touches HTML Clay's own config tree, in either
	// direction. The app owns it because only the app knows where that tree is.
	Guard func(dir string) bool
}

Policy answers "may this folder be trusted, and on whose say-so".

func (Policy) Canonical

func (p Policy) Canonical(dir string) (string, error)

Canonical resolves and validates a folder the user asked to trust, returning the canonical path to store. The folder must resolve, sit strictly inside home (so home itself is refused), carry no hidden component, and not be HTML Clay's own config/versions tree. Storing the same canonical form the session manager keys its roots on is what keeps live-revoke able to find the root later.

It is also where one directory is reduced to one spelling: every door that records a trusted folder passes through here, so normalizing the capitalization at this single point is what stops the list, the remembered ports, and siteAtLocked from each seeing two folders where there is one.

func (Policy) IsPersonal

func (p Policy) IsPersonal(dir string) bool

IsPersonal reports whether dir is exactly one of the personal folders. The tray picker uses it to warn before trusting one; unlike the two rules above it refuses nothing, because a deliberate act with a folder picker may choose anything Canonical accepts.

func (Policy) RefuseOwnFolder

func (p Policy) RefuseOwnFolder(dir string) bool

RefuseOwnFolder reports whether dir is a personal folder, or an ancestor that would swallow one.

This is the rule for the route where the folder is pinned to a file the user acted on: it is always the requesting file's own directory, so a page cannot inflate it. That makes the looser test correct here, and the stricter one wrong: ~/Documents/GitHub/myproject must stay trustable by a file inside it. A folder INSIDE a personal folder is therefore allowed, which is the whole difference from RefuseSteered.

Comparison is by identity (os.SameFile) as well as case-folded path, so a casing alias or a symlinked variant of a personal folder cannot slip through as a different spelling. The ancestor test runs against the resolved forms personalDirs supplies, so a folder that CONTAINS a relocated personal folder is refused too: with ~/Documents -> ~/relocated/Documents, a file in ~/relocated asking to trust its own folder would otherwise take the whole real Documents tree, since os.SameFile only ever answered for dir BEING a personal folder.

func (Policy) RefuseSteered

func (p Policy) RefuseSteered(dir string) bool

RefuseSteered reports whether dir is a personal folder, sits inside one, or is an ancestor that would swallow one.

This is the rule for the route where the PAGE steers which folder is named. The read prompt offers to trust the common ancestor of the requesting file and the asset it asked for, and a page picks its own assets: two requests under different subfolders make their common ancestor the whole of Documents. One click would then durably trust everything the user owns.

Note what that means in practice, because it is broader than it first reads and the honest case does pay for it: ANYTHING under a personal folder is refused on this route, so someone whose projects live in ~/Documents or ~/Desktop never sees this button. The other two doors are still open to them, the banner on a file they opened (RefuseOwnFolder, which allows exactly that case) and the tray picker, which consults none of this because choosing a folder from a picker is already a deliberate act.

dir arrives already symlink-resolved, and personalDirs supplies each name in both its lexical and its resolved form, so a personal folder that is itself a symlink is recognized under either name.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL