Documentation
¶
Overview ¶
Package axtverify verifies that an organization's Access Transparency events are included in its transparency log, using only trust decided locally: the log key this release ships, or one the operator supplies. The cmd/axt-verify tool is a thin command line over it.
Index ¶
- Constants
- Variables
- func BuiltinFingerprint() (string, bool)
- func BuiltinVerifierKey(orgUUID string) (string, bool)
- func Fingerprint(der []byte) string
- func FingerprintOfVerifierKey(vkey string) (string, bool)
- func KeyHash(vkey string) (string, bool)
- func Origin(orgUUID string) string
- func ReadBaselineNote(raw []byte, v *checkpoint.Verifier, trusted bool) (checkpoint.Checkpoint, error)
- func VerifierKeyFor(origin string, der []byte) string
- type Baseline
- type CheckpointReport
- type DoneEvent
- type EventFailure
- type EventReport
- type FeedState
- type Inconsistency
- type InconsistencyError
- type PendingEvent
- type Report
- type State
- type Verifier
Constants ¶
const OriginPrefix = "axt.anthropic.com"
OriginPrefix is the production log's origin name, the part before the organization UUID. It is a constant rather than a setting: a customer verifies their own log, and there is only one production deployment of it.
Variables ¶
var ErrLogAdvancing = errors.New("the log advanced repeatedly during verification; rerun")
ErrLogAdvancing means the log published new checkpoints faster than one run could relate them; rerunning resolves it.
var ErrVerification = errors.New("verification failed")
ErrVerification marks a failed cryptographic check: a checkpoint, consistency or inclusion proof that does not stand up. Every one of these is a finding about the log, not about this tool, and callers separate them from transport trouble on that basis.
Functions ¶
func BuiltinFingerprint ¶
BuiltinFingerprint is the published fingerprint of the key this release ships, so the tool can name what it is trusting.
func BuiltinVerifierKey ¶
BuiltinVerifierKey is the note-verifier string this release verifies an organization's log with.
func Fingerprint ¶
Fingerprint is the value published for a key and printed in the README, so an operator can see that a release ships the key they expect.
func FingerprintOfVerifierKey ¶
FingerprintOfVerifierKey is the published fingerprint — SHA-256 of the key's DER SubjectPublicKeyInfo — of the key a verifier string carries.
It is derivable only from the ECDSA form this log signs with, whose payload is 0x02 || SPKI. A standard Ed25519 note key carries 0x01 || the raw 32-byte key, and the SPKI cannot be recovered from that, so hashing the payload would print a number that matches nothing anyone published. Callers that must show something for any key use KeyHash.
func KeyHash ¶
KeyHash is the 8-hex key hash a verifier string carries: the value a note signature is matched by, and the one field that is meaningful for every key encoding.
func Origin ¶
Origin is the log origin for an organization: the fixed prefix and the organization's UUID, which is exactly the line every checkpoint must carry.
func ReadBaselineNote ¶
func ReadBaselineNote(raw []byte, v *checkpoint.Verifier, trusted bool) (checkpoint.Checkpoint, error)
ReadBaselineNote finds a signed checkpoint note in what the caller handed over. It is liberal about the container — the raw note, a --json report, or a state file all carry one — and strict about the note itself: verify decides whether the signatures must check out, and the origin is enforced either way.
func VerifierKeyFor ¶
VerifierKeyFor builds the note-verifier string for an ECDSA P-256 key, the one encoding the log signs under: "<origin>+<8 hex>+base64(0x02 || SPKI)". This is the exact encoding the log's published keys use, so any tooling that renders a key for this log must produce these bytes.
Types ¶
type Baseline ¶
type Baseline struct {
Checkpoint checkpoint.Checkpoint
// Label says where it came from, for the pass's own output.
Label string
}
Baseline is a checkpoint the caller keeps for itself — yesterday's archived note, or a size and root hash recorded elsewhere — that this pass must prove the log still extends.
type CheckpointReport ¶
type CheckpointReport struct {
Size uint64 `json:"size"`
RootHash []byte `json:"root_hash"`
// Note is the signed checkpoint exactly as served, so a caller can keep
// it as its own record of what this pass verified.
Note string `json:"note,omitempty"`
}
CheckpointReport describes the newest checkpoint verified in the pass.
type DoneEvent ¶
type DoneEvent struct {
CreatedAt time.Time `json:"created_at"`
// Index is the verified leaf index; nil for an event served with no leaf.
Index *uint64 `json:"leaf_index"`
// LeafHash is the leaf hash that verified, so a re-listing of the same
// id inside the overlap window is checked against it rather than
// trusted.
LeafHash []byte `json:"leaf_hash,omitempty"`
// RecordedAt is when this pass verified the event, by the verifier's own
// clock. Retention keys on it rather than on the served created_at,
// which a serving path could backdate to have the record — the only
// detector of a later index withdrawal — pruned early.
RecordedAt time.Time `json:"recorded_at,omitzero"`
}
DoneEvent is a processed event.
type EventFailure ¶
type EventFailure struct {
ID string `json:"id"`
Index *uint64 `json:"leaf_index,omitempty"`
Reason string `json:"reason"`
}
EventFailure is one event that failed verification.
type EventReport ¶
type EventReport struct {
// Verified events have a valid inclusion proof for their rebuilt leaf.
Verified int `json:"verified"`
// NotLogged events were served with a null leaf index: recorded while
// the organization had no active log. Expected before enrollment and
// in a sealed gap. They are reported, never failed: the absence of an
// index is served, not committed, so there is nothing to verify it
// against.
NotLogged []string `json:"not_logged"`
// Pending events carry a leaf index no published checkpoint covers yet.
Pending []string `json:"pending"`
// Failed events could not be verified; each is a finding to escalate.
Failed []EventFailure `json:"failed"`
// SkippedOtherTypes counts rows that are not Access Transparency records
// at all — other activity types in the same feed or export. They are not
// this tool's to check, and passing over them is not a finding.
SkippedOtherTypes int `json:"skipped_other_types"`
}
EventReport tallies the events examined.
type FeedState ¶
type FeedState struct {
// HighWater is the newest created_at processed. The next run re-reads
// an overlap window behind it because events become listable after an
// ingestion delay, out of created_at order.
HighWater time.Time `json:"high_water,omitzero"`
// Done records events inside the overlap window that need no further
// work (verified, or permanently without a leaf), keyed by activity id.
Done map[string]DoneEvent `json:"done,omitempty"`
// Pending records events whose leaf index no published checkpoint
// covered yet, keyed by activity id.
Pending map[string]PendingEvent `json:"pending,omitempty"`
}
FeedState tracks progress through the activity feed.
type Inconsistency ¶
type Inconsistency struct {
// Older and Newer are the two signed notes, verbatim.
Older string `json:"older"`
Newer string `json:"newer"`
// Proof is the consistency proof the log served between them, base64.
Proof []string `json:"proof"`
}
Inconsistency is everything needed to show that a log broke its append-only promise, without asking that log anything further. A verifier that reported only "consistency proof failed" would leave the customer holding a claim they cannot substantiate once the misbehaving server stops answering — or starts answering differently.
type InconsistencyError ¶
type InconsistencyError struct {
Evidence Inconsistency
Err error
}
InconsistencyError is a verification failure carrying that evidence.
func AsInconsistency ¶
func AsInconsistency(err error) (*InconsistencyError, bool)
AsInconsistency extracts the evidence from an error chain, if it carries any.
func (*InconsistencyError) Details ¶
func (e *InconsistencyError) Details() string
Details renders the evidence for a human, and for whoever they forward it to: both notes in full and the proof the log offered between them.
func (*InconsistencyError) Error ¶
func (e *InconsistencyError) Error() string
func (*InconsistencyError) Unwrap ¶
func (e *InconsistencyError) Unwrap() []error
type PendingEvent ¶
type PendingEvent struct {
Index uint64 `json:"leaf_index"`
LeafHash []byte `json:"leaf_hash"`
CreatedAt time.Time `json:"created_at,omitzero"`
FirstSeen time.Time `json:"first_seen"`
}
PendingEvent is an event awaiting a covering checkpoint. LeafHash lets a later run verify it without re-reading the event.
type Report ¶
type Report struct {
Origin string `json:"origin"`
// Inconsistency carries the evidence of a broken append-only property,
// when that is why the pass failed.
Inconsistency *Inconsistency `json:"inconsistency,omitempty"`
Checkpoint CheckpointReport `json:"checkpoint"`
// PreviousSize is the tree size of the checkpoint the append-only check
// started from; nil on a first run.
PreviousSize *uint64 `json:"previous_size"`
Events EventReport `json:"events"`
// Truncated is set when MaxPages stopped the feed read early.
Truncated bool `json:"truncated,omitempty"`
}
Report summarizes one pass. Failed events and a non-nil error from the pass are the two ways verification can fail; everything else is informational.
type State ¶
type State struct {
Version int `json:"version"`
// Origin guards against pointing one organization's state at another's
// configuration.
Origin string `json:"origin"`
// Checkpoint is the signed note of the newest checkpoint verified so far.
Checkpoint string `json:"checkpoint,omitempty"`
// VerifiedAt is when Checkpoint was verified.
VerifiedAt time.Time `json:"verified_at,omitzero"`
Feed FeedState `json:"feed"`
// contains filtered or unexported fields
}
State is what one run leaves for the next: the last checkpoint it verified (the anchor for the append-only check) and how far through the activity feed it got. It holds no secrets and no event content.
func LoadState ¶
LoadState reads path; a missing file yields an empty state for origin. A state written for a different origin is an error.
func (*State) Save ¶
Save writes the state to path atomically with owner-only permissions. It refuses to overwrite a file that changed since LoadState read it — two overlapping invocations sharing one state file must fail loudly rather than have one silently discard the other's verified checkpoint. This detects that collision; it is not a lock, and the README tells a concurrent schedule to use a state file of its own.
type Verifier ¶
type Verifier struct {
Checkpoints *checkpoint.Verifier
Client *compliance.Client
// Baselines are checkpoints the caller keeps for itself — an archived
// note, or a bare (size, hash) pair. Each must be a prefix of what this
// pass verifies, on top of whatever the state file already ratchets.
Baselines []Baseline
// Overlap is how far behind the feed high-water mark each run
// re-reads (default 168h). It must exceed the feed's ingestion and
// delivery delays so late-listed events are not skipped.
Overlap time.Duration
// PendingGrace is how long an event may wait for a covering checkpoint
// before that becomes a failure (default 24h).
PendingGrace time.Duration
// CoverageWait bounds how long `events` waits for a checkpoint covering
// an index it was handed (default 60s). `run` never waits: it remembers
// the event and settles it on a later pass.
CoverageWait time.Duration
// CoveragePoll is how often that wait re-reads the log (default 15s,
// the log's publish cadence).
CoveragePoll time.Duration
// PageSize is the feed page size (default 1000).
PageSize int
// MaxPages bounds feed pages per run; zero is unbounded. A bounded run
// reports Truncated and resumes where it stopped.
MaxPages int
// Now is time.Now unless replaced.
Now func() time.Time
// Logf receives progress lines; nil discards them.
Logf func(format string, args ...any)
}
Verifier runs verification passes for one organization's log.
func (*Verifier) Run ¶
Run is the scheduled pass: verify the latest checkpoint and the append-only property, then read the organization's Access Transparency events from the activity feed — everything since the last run, plus an overlap window — and verify each one's inclusion. Progress is recorded in st, which the caller saves.
func (*Verifier) VerifyCheckpoint ¶
VerifyCheckpoint fetches and verifies the latest checkpoint and, given a state with an earlier one, the append-only property since. On success the state's checkpoint advances.
func (*Verifier) VerifyEvents ¶
func (v *Verifier) VerifyEvents(ctx context.Context, st *State, events []json.RawMessage) (Report, error)
VerifyEvents verifies served events supplied by the caller (a feed page, a SIEM export). st may be nil; when given, the append-only check runs and the state's checkpoint advances.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package checkpoint verifies transparency-log checkpoints against a pinned trust policy — the log's origin and the log's note-verifier key — and verifies Merkle proofs against verified checkpoints.
|
Package checkpoint verifies transparency-log checkpoints against a pinned trust policy — the log's origin and the log's note-verifier key — and verifies Merkle proofs against verified checkpoints. |
|
cmd
|
|
|
axt-verify
command
Command axt-verify checks that Anthropic's Access Transparency log for your organization is what it claims to be: correctly signed, append-only, and committing to the events the Compliance API serves you.
|
Command axt-verify checks that Anthropic's Access Transparency log for your organization is what it claims to be: correctly signed, append-only, and committing to the events the Compliance API serves you. |
|
Package compliance is a client for the slice of the Anthropic Compliance API that axt-verify reads: an organization's transparency log (/v1/compliance/transparency_log/…) and its Access Transparency events on the activity feed (/v1/compliance/activities).
|
Package compliance is a client for the slice of the Anthropic Compliance API that axt-verify reads: an organization's transparency log (/v1/compliance/transparency_log/…) and its Access Transparency events on the activity feed (/v1/compliance/activities). |
|
internal
|
|
|
testlog
Package testlog is an in-memory transparency log and a fake of the Compliance API surface axt-verify reads, for hermetic tests.
|
Package testlog is an in-memory transparency log and a fake of the Compliance API surface axt-verify reads, for hermetic tests. |
|
Package leaf rebuilds Access Transparency transparency-log leaf entries from events exactly as the Compliance API activity feed serves them.
|
Package leaf rebuilds Access Transparency transparency-log leaf entries from events exactly as the Compliance API activity feed serves them. |