trustedagents

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: May 28, 2026 License: AGPL-3.0 Imports: 14 Imported by: 0

README

trustedagents

ci codecov

Trusted-agents plugin for the Pilot Protocol daemon. Ships an embedded allowlist of public node IDs that the daemon auto-accepts handshake requests from, plus a 1-hour refresher loop that pulls the canonical list from this repo on a schedule.

Install

import "github.com/pilot-protocol/trustedagents"

Usage

// Lookup:
name, ok := trustedagents.IsTrusted(nodeID)
_ = name
_ = ok

// Daemon registration:
rt.Register(trustedagents.NewService())

Layout

File What it does
data.go Embedded JSON list. Load, All, IsTrusted(nodeID) → (description, ok), SetForTest.
runtime.go Run(ctx) — periodic fetcher over HTTPS to raw.githubusercontent.com.
service.go *Servicecoreapi.Service adapter (Name/Order/Start/Stop + IsTrusted). Build tag !no_trustedagents.
service_disabled.go Stub *Service when build tag no_trustedagents is set.
trusted-agents.json The list itself. PRs adding entries land here.

Updating the list

Edit trusted-agents.json and open a PR. Once merged, daemons in the field pick up the new list on their next 1-hour refresh tick. Brand-new daemons get the embedded copy compiled into the binary.

Build tags

Tag Effect
no_trustedagents Compiles a stub that always returns ("", false) from IsTrusted. Used by integration tests that need a clean trust state.

License

AGPL-3.0-or-later. See LICENSE.

Documentation

Overview

Package trustedagents holds the build-time-embedded list of node IDs that the daemon auto-accepts handshake requests from. The data layer is utility-tier so both the daemon plugin (plugins/trustedagents) and the CLI (cmd/pilotctl) can read it without violating the strict downward layer rule.

The list is plain JSON in this directory, embedded at build time and refreshed hourly from raw.githubusercontent.com by plugins/trustedagents.Run. Authenticity comes from HTTPS to GitHub plus repo write access — there is no separate signature check.

Adding an agent: edit trusted-agents.json, commit. Daemons in the field pick it up within ~1h. Brand-new daemons get the embedded copy from the binary, so the feature works on first boot even airgapped.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EmbeddedJSON

func EmbeddedJSON() []byte

EmbeddedJSON returns the bytes of the embedded JSON list. Exposed for the plugin's HTTP refresher which needs to compare fetched bytes against the embedded baseline at startup.

func IsTrusted

func IsTrusted(nodeID uint32) (string, bool)

IsTrusted reports whether nodeID is in the trusted-agents list. The caller MUST verify the (node_id, public_key) binding at the registry before acting on a true result — this package only checks the list.

func Load

func Load(raw []byte) error

Load parses raw JSON and atomically replaces the active list. Safe to call from any goroutine. Used by plugins/trustedagents.fetchOnce after each successful HTTP refresh.

func Run

func Run(ctx context.Context)

Run polls the canonical URL on a timer, replacing the active list whenever a new one is fetched. Blocks until ctx is cancelled. The first fetch is delayed 0–30s so a fleet rebooting at the same time doesn't thunder the URL.

func SetForTest

func SetForTest(agents []Agent) (restore func())

SetForTest replaces the active list with agents and returns a restore function that reloads the embedded list. Test-only — never call from production code.

func VerifyAndStripSig

func VerifyAndStripSig(raw []byte) ([]byte, error)

VerifyAndStripSig checks the ed25519 signature embedded in the fetched JSON. If no "signature" field is present the raw body is returned as-is (backward-compatible with unsigned lists). If the field is present the signature is verified against embeddedPubKey; on mismatch an error is returned so the caller falls back to the embedded list.

Types

type Agent

type Agent struct {
	Hostname string `json:"hostname"`
	Address  string `json:"address"`
	NodeID   uint32 `json:"node_id"`
}

Agent is one entry in the trusted-agents list. Match is by NodeID; Hostname and Address are kept for logs and `pilotctl trusted list`. Other JSON fields in the source file (tier, description, ...) are silently ignored on unmarshal — we don't care about them at runtime.

func All

func All() []Agent

All returns a copy of the current list. Used by `pilotctl trusted list`.

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service is the L11 plugin adapter. Implements both coreapi.Service (lifecycle) and coreapi.TrustChecker (trust gate). Daemon stores it twice — once in the plugin registry, once as the trust checker — but it's the same struct.

func NewService

func NewService() *Service

NewService returns a Service ready for daemon.RegisterPlugin and daemon.RegisterTrustChecker.

func (*Service) IsTrusted

func (s *Service) IsTrusted(nodeID uint32) (string, bool)

IsTrusted is the coreapi.TrustChecker side of the plugin. Delegates to the package-global allowlist that Run() maintains.

func (*Service) Name

func (s *Service) Name() string

func (*Service) Order

func (s *Service) Order() int

Order: 50 — must start BEFORE handshake (~order 70) so the allowlist is populated when the first trust handshake arrives.

func (*Service) Start

func (s *Service) Start(ctx context.Context, deps coreapi.Deps) error

func (*Service) Stop

func (s *Service) Stop(ctx context.Context) error

Jump to

Keyboard shortcuts

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