Files
substrate/tools/apitool
Max Thompson 72e7906ad1 ateapi: validate system-info projection paths at template creation (#1439)
`CreateActorTemplate` accepted `../escape` and `/escaped` in
`ActorMetadataItem.path` and `TrustBundleDataSource.path`, and accepted
several data sources projecting to the same path. atelet only rejects
the traversal at actor start, so the template is created but the golden
actor sits in `RESUMING`. atelet never rejects duplicate paths at all:
it writes the files in order and the last one wins.

This PR moves both checks to template validation.

- The path rule lives in a new `internal/volumepath` package that both
ateapi and atelet call, so the two cannot drift. It splits on `/` and
rejects any segment that is empty, `.`, or `..`, caps depth at 16
segments, and rejects NUL bytes. Any other byte is allowed, so Unicode
paths pass. `ActorMetadataItem.path` and `TrustBundleDataSource.path`
apply it through a `+k8s:customValidation` hook, and atelet's
`writeSystemInfoFile` applies it again before touching the host
filesystem.
- `SystemInfoVolumeSource.data_sources` gets a hook that tracks
projected paths in a set and reports a duplicate on repeats, in the same
shape as the Kubernetes projected-volume validation.

The proto doc comment on `data_sources` also says at most one
`actor_metadata` entry may appear. Nothing enforces that, and this PR
leaves it alone.

New cases in `TestValidateSystemInfoVolumeSource` and
`TestValidateTrustBundleDataSource` cover the rejected shapes, and
`internal/volumepath` has its own table test. `hack/verify/codegen.sh`
and `hack/verify/golangci-lint.sh` pass.

#1231 moves `writeSystemInfoFile` into `systeminfovolume.go` and onto
`os.Root`. Whichever PR lands second points that copy at the shared
rule.

Fixes #1436
Fixes #1438
2026-09-04 16:32:34 -07:00
..

Substrate API Tool (apitool)

The apitool is a CLI that automates tasks related to the Substrate API.

Usage

cd tools/apitool
go run . validate

validate runs the rules in internal/lint against ateapi.proto and fails if any rule reports a finding that isn't exempted (see below).

Exemptions

Findings can be exempted via exemptions.json. To regenerate exemptions.json so it matches every current finding exactly (e.g. after fixing some findings, or before adding new ones you plan to exempt), run:

go run . validate --update

Review the diff to exemptions.json like any other change: a shrinking diff means findings got fixed, a growing one means new violations are being exempted rather than fixed.

The matching is strict meaning that both an extra exemption and a missing one will cause a failure. This helps during review to guarantee that the changes in the exemptions file really reflects the state of the system.

A unit test enforces this same strict matching as a presubmit gate.

go test ./internal/validate/... -run TestExemptions