Skip to content

feat(audit): canonical, fully signed entry format (v2) with registered-key verification #2000

Description

@MastaP

Summary

Define a v2 audit entry format:

  • a canonical encoding that verifiers outside Rust can recompute;
  • every field signed;
  • verification against registered keys instead of the key embedded in each
    entry.

Motivation

AuditEntry::signing_data (crates/astrid-audit/src/entry.rs:123) is hard to
verify independently:

  • Encoding: it mixes fixed binary fields with serde_json of the action
    and authorization, and silently omits either if serialization fails
    (entry.rs:143,146).
  • Time: it signs whole-second time (entry.rs:126).
  • Outcome: it reduces the outcome to one success/failure bit, so the
    outcome text is not signed.
  • Position: there is no signed per-chain sequence number.
  • Keys: verification uses the public key embedded in each entry. Anyone
    with write access to the store can therefore re-sign a rewritten chain
    under any key and still pass.
  • Key roles: one runtime key signs audit entries, capability tokens and
    build artifacts.

External verification (#1995, #678) and receipts (#693, #1367) need a format
that can be recomputed byte for byte outside Astrid.

Proposed Implementation

  • EntryV2: a deterministic CBOR positional array hashed with
    domain-separated SHA-256 and signed with Ed25519 (verify_strict).
    • Chain and position fields: chain id bound to the principal UID, per-chain
      sequence number and previous hash.
    • Content fields: nanosecond time, actor (capsule id and wasm hash), full
      outcome, salted commitments for sensitive or low-entropy fields.
    • A format version.
  • Key roles: separate keys for audit, capability issuance and build
    signing, with a key registry chain (genesis and rotations cross-signed).
    Verifiers reject entries signed by unregistered keys. This relates to feat(cli): astrid keys — runtime key inspection, rotation, pubkey export for trust setup #683.
  • Migration: v1 chains are closed and kept verifiable as they are; new
    entries are v2. External anchoring keeps working across the switch.

Alternatives Considered

  • Canonicalize JSON (RFC 8785) and keep the layout. Smaller change, but
    the one-bit outcome, missing sequence number and embedded-key verification
    remain.

Part of #1997.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions