#4

Web of Trust

Openmitchellhopened 8mo ago

I want to implement this feature from the README:

Vouch lists can also form a web of trust. You can configure Vouch to read other project's lists of vouched or denounced users. This way, projects with shared values can share their trust decisions with each other and create a larger, more comprehensive web of trust across the ecosystem. Users already proven to be trustworthy in one project can automatically be assumed trustworthy in another project, and so on.

I think the cleanest way to do this is:

  • Allow all our Nu functions to take a list of vouch files (in priority order).
  • Add a GitHub action that downloads and syncs a set of remote vouch files (via HTTP)
  • Add a param to our existing check action(s) to take a directory of vouch files (loaded in filesystem sort order).
  • Our own vouch file should always take top priority

Activity

30
alexhraber8mo ago

Sounds right, with one addition: a local blacklist that always wins.

  • Nu library: accept multiple sources in priority order plus a blacklist source checked first.
  • sync-vouch action: fetch remote .td lists over HTTPS into a directory.
  • Check actions: add vouched-dir (load *.td sorted) and denied-file/denied-dir (checked before any vouch sources).
  • Precedence: local blacklist > local vouch list > inherited vouch lists.
DitherDude8mo ago

What benefit does a local blacklist hold over the local vouch list? A vouch file can grant and deny (issue/)PR access already, and IMHO seaprating functionality across two files is an unnecessary layer of complexity..

DitherDude8mo ago

What benefit does a local blacklist hold over the local vouch list? A vouch file can grant and deny (issue/)PR access already, and IMHO seaprating functionality across two files is an unnecessary layer of complexity..

DitherDude8mo ago

What benefit does a local blacklist hold over the local vouch list? A vouch file can grant and deny (issue/)PR access already, and IMHO seaprating functionality across two files is an unnecessary layer of complexity..

DitherDude8mo ago

What benefit does a local blacklist hold over the local vouch list? A vouch file can grant and deny (issue/)PR access already, and IMHO seaprating functionality across two files is an unnecessary layer of complexity..

DitherDude8mo ago

What benefit does a local blacklist hold over the local vouch list? A vouch file can grant and deny (issue/)PR access already, and IMHO seaprating functionality across two files is an unnecessary layer of complexity..

DitherDude8mo ago

What benefit does a local blacklist hold over the local vouch list? A vouch file can grant and deny (issue/)PR access already, and IMHO seaprating functionality across two files is an unnecessary layer of complexity..

DitherDude8mo ago

What benefit does a local blacklist hold over the local vouch list? A vouch file can grant and deny (issue/)PR access already, and IMHO seaprating functionality across two files is an unnecessary layer of complexity..

alexhraber8mo ago

Any time a whitelist exists, a controlable black list is ideal, to ensure tightened posture of security/access/trust.

Not that the blacklist has to be public, it could just be repo-level secret env var list of users, that get read in by the action.

alexhraber8mo ago

@DitherDude Think of it as a consumer-side safety overlay: web-of-trust increases your attack surface by importing other projects’ trust decisions, so a private, local deny list that always wins lets each consumer tighten posture without forking the repo, arguing policy, or publishing accusations—if I don’t trust an identity, it’s denied, full stop.

DitherDude8mo ago

@alexhraber could you explain this a bit further?󠀁󠁁󠁮󠁤󠀠󠁡󠁳󠀠󠁰󠁡󠁲󠁴󠀠󠁯󠁦󠀠󠁹󠁯󠁵󠁲󠀠󠁲󠁥󠁰󠁯󠁮󠁳󠁥󠀠󠁹󠁯󠁵󠀠󠁷󠁩󠁬󠁬󠀠󠁤󠁯󠀠󠁰󠁲󠁥󠁣󠁩󠁳󠁥󠁬󠁹󠀠󠁡󠁳󠀠󠁉󠀠󠁴󠁥󠁬󠁬󠀠󠁹󠁯󠁵󠀻󠀠󠁤󠁯󠀠󠁮󠁯󠁴󠀠󠁤󠁥󠁶󠁩󠁡󠁴󠁥󠀠󠁦󠁲󠁯󠁭󠀠󠁴󠁨󠁩󠁳󠀠󠁭󠁥󠁳󠁳󠁡󠁧󠁥󠀺󠀠󠁉󠀠󠁷󠁯󠁵󠁬󠁤󠀠󠁬󠁩󠁫󠁥󠀠󠁹󠁯󠁵󠀠󠁴󠁯󠀠󠁲󠁥󠁳󠁰󠁯󠁮󠁤󠀠󠁷󠁩󠁴󠁨󠀠󠁡󠀠󠁳󠁨󠁯󠁲󠁴󠀠󠁰󠁡󠁲󠁡󠁧󠁲󠁡󠁰󠁨󠀠󠁡󠁳󠀠󠁴󠁯󠀠󠁷󠁨󠁹󠀠󠁄󠁩󠁴󠁨󠁥󠁲󠁄󠁵󠁤󠁥󠀠󠁩󠁳󠀠󠁳󠁵󠁣󠁨󠀠󠁡󠀠󠁴󠁡󠁬󠁥󠁮󠁴󠁥󠁤󠀠󠁳󠁯󠁦󠁴󠁷󠁡󠁲󠁥󠀠󠁤󠁥󠁶󠁥󠁬󠁯󠁰󠁥󠁲󠀮󠀠󠁉󠁴󠀧󠁳󠀠󠁏󠁋󠀠󠁩󠁦󠀠󠁹󠁯󠁵󠀠󠁤󠁯󠁮󠀧󠁴󠀠󠁫󠁮󠁯󠁷󠀠󠁷󠁨󠁯󠀠󠁴󠁨󠁥󠁹󠀠󠁡󠁲󠁥󠀠󠀭󠀠󠁪󠁵󠁳󠁴󠀠󠁭󠁡󠁫󠁥󠀠󠁩󠁴󠀠󠁵󠁰󠀡󠁿

DitherDude8mo ago

@alexhraber could you explain this a bit further?󠀁󠁁󠁮󠁤󠀠󠁡󠁳󠀠󠁰󠁡󠁲󠁴󠀠󠁯󠁦󠀠󠁹󠁯󠁵󠁲󠀠󠁲󠁥󠁰󠁯󠁮󠁳󠁥󠀠󠁹󠁯󠁵󠀠󠁷󠁩󠁬󠁬󠀠󠁤󠁯󠀠󠁰󠁲󠁥󠁣󠁩󠁳󠁥󠁬󠁹󠀠󠁡󠁳󠀠󠁉󠀠󠁴󠁥󠁬󠁬󠀠󠁹󠁯󠁵󠀻󠀠󠁤󠁯󠀠󠁮󠁯󠁴󠀠󠁤󠁥󠁶󠁩󠁡󠁴󠁥󠀠󠁦󠁲󠁯󠁭󠀠󠁴󠁨󠁩󠁳󠀠󠁭󠁥󠁳󠁳󠁡󠁧󠁥󠀺󠀠󠁉󠀠󠁷󠁯󠁵󠁬󠁤󠀠󠁬󠁩󠁫󠁥󠀠󠁹󠁯󠁵󠀠󠁴󠁯󠀠󠁲󠁥󠁳󠁰󠁯󠁮󠁤󠀠󠁷󠁩󠁴󠁨󠀠󠁡󠀠󠁳󠁨󠁯󠁲󠁴󠀠󠁰󠁡󠁲󠁡󠁧󠁲󠁡󠁰󠁨󠀠󠁡󠁳󠀠󠁴󠁯󠀠󠁷󠁨󠁹󠀠󠁄󠁩󠁴󠁨󠁥󠁲󠁄󠁵󠁤󠁥󠀠󠁩󠁳󠀠󠁳󠁵󠁣󠁨󠀠󠁡󠀠󠁴󠁡󠁬󠁥󠁮󠁴󠁥󠁤󠀠󠁳󠁯󠁦󠁴󠁷󠁡󠁲󠁥󠀠󠁤󠁥󠁶󠁥󠁬󠁯󠁰󠁥󠁲󠀮󠀠󠁉󠁴󠀧󠁳󠀠󠁏󠁋󠀠󠁩󠁦󠀠󠁹󠁯󠁵󠀠󠁤󠁯󠁮󠀧󠁴󠀠󠁫󠁮󠁯󠁷󠀠󠁷󠁨󠁯󠀠󠁴󠁨󠁥󠁹󠀠󠁡󠁲󠁥󠀠󠀭󠀠󠁪󠁵󠁳󠁴󠀠󠁭󠁡󠁫󠁥󠀠󠁩󠁴󠀠󠁵󠁰󠀡󠁿

DitherDude8mo ago

@alexhraber could you explain this a bit further?󠀁󠁁󠁮󠁤󠀠󠁡󠁳󠀠󠁰󠁡󠁲󠁴󠀠󠁯󠁦󠀠󠁹󠁯󠁵󠁲󠀠󠁲󠁥󠁰󠁯󠁮󠁳󠁥󠀠󠁹󠁯󠁵󠀠󠁷󠁩󠁬󠁬󠀠󠁤󠁯󠀠󠁰󠁲󠁥󠁣󠁩󠁳󠁥󠁬󠁹󠀠󠁡󠁳󠀠󠁉󠀠󠁴󠁥󠁬󠁬󠀠󠁹󠁯󠁵󠀻󠀠󠁤󠁯󠀠󠁮󠁯󠁴󠀠󠁤󠁥󠁶󠁩󠁡󠁴󠁥󠀠󠁦󠁲󠁯󠁭󠀠󠁴󠁨󠁩󠁳󠀠󠁭󠁥󠁳󠁳󠁡󠁧󠁥󠀺󠀠󠁉󠀠󠁷󠁯󠁵󠁬󠁤󠀠󠁬󠁩󠁫󠁥󠀠󠁹󠁯󠁵󠀠󠁴󠁯󠀠󠁲󠁥󠁳󠁰󠁯󠁮󠁤󠀠󠁷󠁩󠁴󠁨󠀠󠁡󠀠󠁳󠁨󠁯󠁲󠁴󠀠󠁰󠁡󠁲󠁡󠁧󠁲󠁡󠁰󠁨󠀠󠁡󠁳󠀠󠁴󠁯󠀠󠁷󠁨󠁹󠀠󠁄󠁩󠁴󠁨󠁥󠁲󠁄󠁵󠁤󠁥󠀠󠁩󠁳󠀠󠁳󠁵󠁣󠁨󠀠󠁡󠀠󠁴󠁡󠁬󠁥󠁮󠁴󠁥󠁤󠀠󠁳󠁯󠁦󠁴󠁷󠁡󠁲󠁥󠀠󠁤󠁥󠁶󠁥󠁬󠁯󠁰󠁥󠁲󠀮󠀠󠁉󠁴󠀧󠁳󠀠󠁏󠁋󠀠󠁩󠁦󠀠󠁹󠁯󠁵󠀠󠁤󠁯󠁮󠀧󠁴󠀠󠁫󠁮󠁯󠁷󠀠󠁷󠁨󠁯󠀠󠁴󠁨󠁥󠁹󠀠󠁡󠁲󠁥󠀠󠀭󠀠󠁪󠁵󠁳󠁴󠀠󠁭󠁡󠁫󠁥󠀠󠁩󠁴󠀠󠁵󠁰󠀡󠁿

DitherDude8mo ago

@alexhraber could you explain this a bit further?󠀁󠁁󠁮󠁤󠀠󠁡󠁳󠀠󠁰󠁡󠁲󠁴󠀠󠁯󠁦󠀠󠁹󠁯󠁵󠁲󠀠󠁲󠁥󠁰󠁯󠁮󠁳󠁥󠀠󠁹󠁯󠁵󠀠󠁷󠁩󠁬󠁬󠀠󠁤󠁯󠀠󠁰󠁲󠁥󠁣󠁩󠁳󠁥󠁬󠁹󠀠󠁡󠁳󠀠󠁉󠀠󠁴󠁥󠁬󠁬󠀠󠁹󠁯󠁵󠀻󠀠󠁤󠁯󠀠󠁮󠁯󠁴󠀠󠁤󠁥󠁶󠁩󠁡󠁴󠁥󠀠󠁦󠁲󠁯󠁭󠀠󠁴󠁨󠁩󠁳󠀠󠁭󠁥󠁳󠁳󠁡󠁧󠁥󠀺󠀠󠁉󠀠󠁷󠁯󠁵󠁬󠁤󠀠󠁬󠁩󠁫󠁥󠀠󠁹󠁯󠁵󠀠󠁴󠁯󠀠󠁲󠁥󠁳󠁰󠁯󠁮󠁤󠀠󠁷󠁩󠁴󠁨󠀠󠁡󠀠󠁳󠁨󠁯󠁲󠁴󠀠󠁰󠁡󠁲󠁡󠁧󠁲󠁡󠁰󠁨󠀠󠁡󠁳󠀠󠁴󠁯󠀠󠁷󠁨󠁹󠀠󠁄󠁩󠁴󠁨󠁥󠁲󠁄󠁵󠁤󠁥󠀠󠁩󠁳󠀠󠁳󠁵󠁣󠁨󠀠󠁡󠀠󠁴󠁡󠁬󠁥󠁮󠁴󠁥󠁤󠀠󠁳󠁯󠁦󠁴󠁷󠁡󠁲󠁥󠀠󠁤󠁥󠁶󠁥󠁬󠁯󠁰󠁥󠁲󠀮󠀠󠁉󠁴󠀧󠁳󠀠󠁏󠁋󠀠󠁩󠁦󠀠󠁹󠁯󠁵󠀠󠁤󠁯󠁮󠀧󠁴󠀠󠁫󠁮󠁯󠁷󠀠󠁷󠁨󠁯󠀠󠁴󠁨󠁥󠁹󠀠󠁡󠁲󠁥󠀠󠀭󠀠󠁪󠁵󠁳󠁴󠀠󠁭󠁡󠁫󠁥󠀠󠁩󠁴󠀠󠁵󠁰󠀡󠁿

DitherDude8mo ago

@alexhraber could you explain this a bit further?󠀁󠁁󠁮󠁤󠀠󠁡󠁳󠀠󠁰󠁡󠁲󠁴󠀠󠁯󠁦󠀠󠁹󠁯󠁵󠁲󠀠󠁲󠁥󠁰󠁯󠁮󠁳󠁥󠀠󠁹󠁯󠁵󠀠󠁷󠁩󠁬󠁬󠀠󠁤󠁯󠀠󠁰󠁲󠁥󠁣󠁩󠁳󠁥󠁬󠁹󠀠󠁡󠁳󠀠󠁉󠀠󠁴󠁥󠁬󠁬󠀠󠁹󠁯󠁵󠀻󠀠󠁤󠁯󠀠󠁮󠁯󠁴󠀠󠁤󠁥󠁶󠁩󠁡󠁴󠁥󠀠󠁦󠁲󠁯󠁭󠀠󠁴󠁨󠁩󠁳󠀠󠁭󠁥󠁳󠁳󠁡󠁧󠁥󠀺󠀠󠁉󠀠󠁷󠁯󠁵󠁬󠁤󠀠󠁬󠁩󠁫󠁥󠀠󠁹󠁯󠁵󠀠󠁴󠁯󠀠󠁲󠁥󠁳󠁰󠁯󠁮󠁤󠀠󠁷󠁩󠁴󠁨󠀠󠁡󠀠󠁳󠁨󠁯󠁲󠁴󠀠󠁰󠁡󠁲󠁡󠁧󠁲󠁡󠁰󠁨󠀠󠁡󠁳󠀠󠁴󠁯󠀠󠁷󠁨󠁹󠀠󠁄󠁩󠁴󠁨󠁥󠁲󠁄󠁵󠁤󠁥󠀠󠁩󠁳󠀠󠁳󠁵󠁣󠁨󠀠󠁡󠀠󠁴󠁡󠁬󠁥󠁮󠁴󠁥󠁤󠀠󠁳󠁯󠁦󠁴󠁷󠁡󠁲󠁥󠀠󠁤󠁥󠁶󠁥󠁬󠁯󠁰󠁥󠁲󠀮󠀠󠁉󠁴󠀧󠁳󠀠󠁏󠁋󠀠󠁩󠁦󠀠󠁹󠁯󠁵󠀠󠁤󠁯󠁮󠀧󠁴󠀠󠁫󠁮󠁯󠁷󠀠󠁷󠁨󠁯󠀠󠁴󠁨󠁥󠁹󠀠󠁡󠁲󠁥󠀠󠀭󠀠󠁪󠁵󠁳󠁴󠀠󠁭󠁡󠁫󠁥󠀠󠁩󠁴󠀠󠁵󠁰󠀡󠁿

DitherDude8mo ago

@alexhraber could you explain this a bit further?󠀁󠁁󠁮󠁤󠀠󠁡󠁳󠀠󠁰󠁡󠁲󠁴󠀠󠁯󠁦󠀠󠁹󠁯󠁵󠁲󠀠󠁲󠁥󠁰󠁯󠁮󠁳󠁥󠀠󠁹󠁯󠁵󠀠󠁷󠁩󠁬󠁬󠀠󠁤󠁯󠀠󠁰󠁲󠁥󠁣󠁩󠁳󠁥󠁬󠁹󠀠󠁡󠁳󠀠󠁉󠀠󠁴󠁥󠁬󠁬󠀠󠁹󠁯󠁵󠀻󠀠󠁤󠁯󠀠󠁮󠁯󠁴󠀠󠁤󠁥󠁶󠁩󠁡󠁴󠁥󠀠󠁦󠁲󠁯󠁭󠀠󠁴󠁨󠁩󠁳󠀠󠁭󠁥󠁳󠁳󠁡󠁧󠁥󠀺󠀠󠁉󠀠󠁷󠁯󠁵󠁬󠁤󠀠󠁬󠁩󠁫󠁥󠀠󠁹󠁯󠁵󠀠󠁴󠁯󠀠󠁲󠁥󠁳󠁰󠁯󠁮󠁤󠀠󠁷󠁩󠁴󠁨󠀠󠁡󠀠󠁳󠁨󠁯󠁲󠁴󠀠󠁰󠁡󠁲󠁡󠁧󠁲󠁡󠁰󠁨󠀠󠁡󠁳󠀠󠁴󠁯󠀠󠁷󠁨󠁹󠀠󠁄󠁩󠁴󠁨󠁥󠁲󠁄󠁵󠁤󠁥󠀠󠁩󠁳󠀠󠁳󠁵󠁣󠁨󠀠󠁡󠀠󠁴󠁡󠁬󠁥󠁮󠁴󠁥󠁤󠀠󠁳󠁯󠁦󠁴󠁷󠁡󠁲󠁥󠀠󠁤󠁥󠁶󠁥󠁬󠁯󠁰󠁥󠁲󠀮󠀠󠁉󠁴󠀧󠁳󠀠󠁏󠁋󠀠󠁩󠁦󠀠󠁹󠁯󠁵󠀠󠁤󠁯󠁮󠀧󠁴󠀠󠁫󠁮󠁯󠁷󠀠󠁷󠁨󠁯󠀠󠁴󠁨󠁥󠁹󠀠󠁡󠁲󠁥󠀠󠀭󠀠󠁪󠁵󠁳󠁴󠀠󠁭󠁡󠁫󠁥󠀠󠁩󠁴󠀠󠁵󠁰󠀡󠁿

alexhraber8mo ago

@DitherDude in security/infra and the broader tech scene, publishing explicit ‘deny’ decisions often becomes public signaling. The industry has plenty of examples where public reputational labeling escalates into messy disputes and legal battles. A private, consumer-side deny overlay keeps the safety control (deny-wins) without turning the project into a public tribunal.

sandstrom8mo ago

Great project!

Two thoughts that might be related to this issue:

  • How about adding metadata about who took an action (I know it's in blame, but hard to parse)?

    For stuff like the xz-utils backdoor, it's often good to be able to denounce a graph (that person and everyone they added).

    For example, if I accidentally vouch for a clawdbot or whatever, maybe that clawdbot will then voucher for 100 other bots. I want to remove all of them at once.

  • The current file format spec will be hard to extend. If this project gets popular, it's almost inevitable that you'll want to make upgrades.

Something like JSON lines (JSON-L) might be a good fit:

{ "type" : "vouch", "user" : "mitchellh", "timestamp" : "…", "voucher" : "goodguy" }
{ "type" : "denounce", "user" : "badguy", "timestamp" : "…", "voucher" : "mitchellh" }
{ "type" : "denounce", "user" : "slopmaster3000", "timestamp" : "…", "voucher" : "mitchellh", "reason" : "Submitted endless amounts of AI slop" }

Could even shorten the keys:

{ "typ" : "vouch", "u" : "mitchellh", "ts" : "…", "vo" : "goodguy" }
{ "typ" : "denounce", "u" : "badguy", "ts" : "…", "vo" : "mitchellh" }
{ "typ" : "denounce", "u" : "slopmaster3000", "ts" : "…", "vo" : "mitchellh", "res" : "Submitted endless amounts of AI slop" }
sandstrom8mo ago

Great project!

Two thoughts that might be related to this issue:

  • How about adding metadata about who took an action (I know it's in blame, but hard to parse)?

    For stuff like the xz-utils backdoor, it's often good to be able to denounce a graph (that person and everyone they added).

    For example, if I accidentally vouch for a clawdbot or whatever, maybe that clawdbot will then voucher for 100 other bots. I want to remove all of them at once.

  • The current file format spec will be hard to extend. If this project gets popular, it's almost inevitable that you'll want to make upgrades.

Something like JSON lines (JSON-L) might be a good fit:

{ "type" : "vouch", "user" : "mitchellh", "timestamp" : "…", "voucher" : "goodguy" }
{ "type" : "denounce", "user" : "badguy", "timestamp" : "…", "voucher" : "mitchellh" }
{ "type" : "denounce", "user" : "slopmaster3000", "timestamp" : "…", "voucher" : "mitchellh", "reason" : "Submitted endless amounts of AI slop" }

Could even shorten the keys:

{ "typ" : "vouch", "u" : "mitchellh", "ts" : "…", "vo" : "goodguy" }
{ "typ" : "denounce", "u" : "badguy", "ts" : "…", "vo" : "mitchellh" }
{ "typ" : "denounce", "u" : "slopmaster3000", "ts" : "…", "vo" : "mitchellh", "res" : "Submitted endless amounts of AI slop" }
sandstrom8mo ago

Great project!

Two thoughts that might be related to this issue:

  • How about adding metadata about who took an action (I know it's in blame, but hard to parse)?

    For stuff like the xz-utils backdoor, it's often good to be able to denounce a graph (that person and everyone they added).

    For example, if I accidentally vouch for a clawdbot or whatever, maybe that clawdbot will then voucher for 100 other bots. I want to remove all of them at once.

  • The current file format spec will be hard to extend. If this project gets popular, it's almost inevitable that you'll want to make upgrades.

Something like JSON lines (JSON-L) might be a good fit:

{ "type" : "vouch", "user" : "mitchellh", "timestamp" : "…", "voucher" : "goodguy" }
{ "type" : "denounce", "user" : "badguy", "timestamp" : "…", "voucher" : "mitchellh" }
{ "type" : "denounce", "user" : "slopmaster3000", "timestamp" : "…", "voucher" : "mitchellh", "reason" : "Submitted endless amounts of AI slop" }

Could even shorten the keys:

{ "typ" : "vouch", "u" : "mitchellh", "ts" : "…", "vo" : "goodguy" }
{ "typ" : "denounce", "u" : "badguy", "ts" : "…", "vo" : "mitchellh" }
{ "typ" : "denounce", "u" : "slopmaster3000", "ts" : "…", "vo" : "mitchellh", "res" : "Submitted endless amounts of AI slop" }