Skip to content

feat(security): replace owned identifiers with BLAKE3#1248

Closed
joshuajbouw wants to merge 8 commits into
mainfrom
agent/owned-blake3
Closed

feat(security): replace owned identifiers with BLAKE3#1248
joshuajbouw wants to merge 8 commits into
mainfrom
agent/owned-blake3

Conversation

@joshuajbouw

@joshuajbouw joshuajbouw commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Linked Issue

Closes #1247

Summary

Replace Astrid-owned SHA-256 identifiers with explicit BLAKE3 semantics before those formats acquire an external compatibility constituency. Content digests remain distinct from domain-separated identifiers, recoverable metadata self-heals, and non-recoverable legacy token indexes fail closed.

Changes

  • add generic IdentifierHash and PublicKeyFingerprint newtypes backed by BLAKE3 derive-key contexts
  • migrate invite and pair-device token indexes to distinct BLAKE3 domains with golden vectors and constant-time comparison coverage
  • prefix raw bearer tokens as astrid_inv_ / astrid_pair_ and serialize fingerprints as blake3:<hex> so secrets and identifiers are self-describing
  • version both token stores; invalidate schema-0 SHA-256 records, preserve unknown future schemas unchanged, and reject malformed state
  • migrate CLI key metadata from schema 1 to schema 2 by recomputing its fingerprint from the retained public key
  • use the shared public-key fingerprint in kernel responses and audit redaction
  • correct MCP binary pins from the inaccurate sha256:<BLAKE3> spelling to blake3:<BLAKE3>, while preserving the existing no-op behavior when an SSE server has no local command to verify
  • document the exact blake3:<64 lowercase hex> local-command pin shape with a syntactically valid example
  • stop logging dictionary-testable fingerprints of low-entropy env values
  • remove unused direct sha2 dependencies from the kernel and gateway while retaining SHA where external protocols require it
  • compose attenuated pair-device authority with the typed BLAKE3 token flow and cover issue, redeem, and revoke in one regression
  • acknowledge the intentional public OpenAPI credential-description change with the required contract marker

Verification

  • exact signed head: f948083f5b7a5461a0ff001f1f2f34cd1d26f387
  • exact base: merged main at 122725708f6b58d3c77c1dc4df4763f345d94c3e
  • the seven source commits are patch-identical to the independently reviewed composition at 1556c728; the restored metadata-only OpenAPI marker leaves the reviewed tree byte-identical, and all eight signatures verify
  • cargo fmt --all -- --check
  • cargo metadata --locked --no-deps --format-version 1
  • git diff --check origin/main..HEAD
  • complete affected-package matrix: 480 CLI, 274 core, 18 crypto, 159 gateway unit plus 35 gateway integration, 277 kernel, 122 MCP, and selected doctests
  • strict all-target/all-feature Clippy across CLI, core, crypto, gateway, kernel, and MCP
  • BLAKE3 derive-key vectors independently reproduced with b3sum --derive-key
  • regression coverage preserves no-command MCP hash behavior while keeping strict BLAKE3 parsing for local binaries
  • combined pair-device regression proves explicit attenuation survives typed-token issue and redeem, then the derived BLAKE3 device identity revokes cleanly
  • independent exact-tree security review found no actionable issues

Dependency Handling

This PR targets main and is restacked directly onto the squash-merged operator-distro boundary. It has no remaining open parent dependency.

Checklist

  • Linked to an issue
  • CHANGELOG.md updated under [Unreleased]

No release is created or published by this change.

Copilot AI review requested due to automatic review settings July 15, 2026 00:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates Astrid-owned identifiers (invite tokens, pair-device tokens, public-key fingerprints, and MCP binary pins) from SHA-256-centric strings to explicit, domain-separated BLAKE3 semantics, aiming to make internal identifiers self-describing and avoid accidental external compatibility commitments.

Changes:

  • Introduces IdentifierHash and PublicKeyFingerprint newtypes (BLAKE3 derive-key domain separation) and updates kernel/CLI/gateway usage to emit blake3:<hex> fingerprints.
  • Versions and migrates invite/pair token stores: schema-0 (legacy SHA-256) fails closed via invalidation; schema-1 persists with typed raw-token prefixes (astrid_inv_ / astrid_pair_) and constant-time comparisons.
  • Updates MCP binary integrity pins to blake3:<hex>, removes SHA-256 env value fingerprint logging in the gateway, and removes direct sha2 deps where no longer needed.

Reviewed changes

Copilot reviewed 25 out of 26 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
e2e/fixtures/compat/legacy-sha-pair-token.toml Adds a compatibility fixture representing a legacy SHA-256 pair-token store record.
e2e/fixtures/compat/legacy-pair-token-without-scope.toml Updates the legacy pair-token fixture to schema 1 and a blake3:<hex> token hash.
docs/gateway-client.md Updates guidance to use BLAKE3 tooling (b3sum) for spec hashing.
docs/distro-signing.md Updates distro signing documentation from sha256 pin examples to BLAKE3 (b3sum).
docs/config.md Updates binary_hash documentation/examples to blake3:<hex>.
crates/astrid-mcp/src/config.rs Enforces blake3:<64 lowercase hex> for MCP binary_hash, rejecting the retired sha256: label; adds tests.
crates/astrid-kernel/src/pair_token.rs Migrates pair-token identifiers to domain-separated BLAKE3, adds schema handling and invalidation for legacy SHA stores, and typed token prefixing.
crates/astrid-kernel/src/kernel_router/admin/pair_device_handlers.rs Updates docs to reflect BLAKE3-based persistence and redaction posture.
crates/astrid-kernel/src/kernel_router/admin/mod.rs Updates audit redaction docs and revoke token fingerprinting to use the new canonicalization helper.
crates/astrid-kernel/src/kernel_router/admin/invite_handlers.rs Switches public-key fingerprinting to shared BLAKE3 helper; updates invite revoke matching logic; adds persistence/revocation tests.
crates/astrid-kernel/src/invite.rs Migrates invite-token identifiers to domain-separated BLAKE3 with schema handling, typed token prefixing, canonicalization helper, and tests.
crates/astrid-kernel/Cargo.toml Removes direct sha2 dependency from the kernel crate.
crates/astrid-integration-tests/tests/compatibility_fixtures.rs Adds an integration test ensuring legacy SHA pair-token stores are invalidated and rewritten.
crates/astrid-gateway/src/routes/invites.rs Updates OpenAPI schema/docs to reflect typed tokens and blake3:<hex> fingerprints.
crates/astrid-gateway/src/routes/env.rs Removes SHA-256 value fingerprint logging to avoid dictionary-testable leakage for low-entropy env values.
crates/astrid-gateway/src/routes/auth.rs Updates request/response docs/examples for typed tokens and BLAKE3 public-key fingerprints.
crates/astrid-gateway/Cargo.toml Removes direct sha2 dependency from the gateway crate and updates comments.
crates/astrid-crypto/src/prelude.rs Re-exports new identifier/fingerprint helpers in the crypto prelude.
crates/astrid-crypto/src/lib.rs Adds the new identifier module and exports IdentifierHash/PublicKeyFingerprint.
crates/astrid-crypto/src/identifier.rs New module implementing domain-separated BLAKE3 identifier types with tests.
crates/astrid-core/src/kernel_api/mod.rs Updates API docs to reflect typed tokens and blake3:<hex> public-key/token fingerprints.
crates/astrid-config/src/defaults.toml Updates default config comments to binary_hash = "blake3:...".
crates/astrid-cli/src/commands/keypair.rs Migrates key metadata to schema 2 with BLAKE3 fingerprints and self-healing migration/repair logic.
crates/astrid-cli/src/commands/invite.rs Updates CLI help/output formatting for blake3:<hex> fingerprints.
CHANGELOG.md Adds an [Unreleased] changelog entry documenting the BLAKE3 identifier migration and related changes.
Cargo.lock Removes now-unused sha2 dependency entries for affected crates.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/astrid-kernel/src/invite.rs Outdated
Comment thread crates/astrid-kernel/src/invite.rs Outdated
Comment thread crates/astrid-kernel/src/pair_token.rs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 25 out of 26 changed files in this pull request and generated no new comments.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 37 out of 38 changed files in this pull request and generated no new comments.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 37 out of 38 changed files in this pull request and generated 4 comments.

Comment thread crates/astrid-config/src/defaults.toml Outdated
Comment thread crates/astrid-capsule/src/profile_cache.rs
Comment thread crates/astrid-capsule/src/profile_cache.rs
Comment thread crates/astrid-capsule/src/profile_cache.rs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 37 out of 38 changed files in this pull request and generated no new comments.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 27 changed files in this pull request and generated no new comments.

API-CONTRACT-CHANGE: pair and invite bearer tokens now expose typed prefixes, and public key and token fingerprints now use the blake3:<hex> format.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 27 changed files in this pull request and generated no new comments.

joshuajbouw added a commit that referenced this pull request Jul 15, 2026
## Linked Issues

Closes #1247
Closes #1249
Closes #1250

## Summary

Complete the pre-release security boundary for Astrid-owned identifiers
and self-managed updates in one reviewed change: domain-separated BLAKE3
identifiers, a BLAKE3-first release-integrity contract with SHA-256
compatibility artifacts, and fail-closed Sigstore publisher
authentication before integrity verification or extraction.

This PR supersedes #1248 and #1251 by containing their exact reviewed
source changes plus the publisher-authentication work originally scoped
here.

## Changes

- add generic `IdentifierHash` and `PublicKeyFingerprint` newtypes
backed by domain-separated BLAKE3
- prefix invite and pair-device bearer tokens, version their stores,
invalidate non-migratable legacy SHA-256 indexes, and preserve unknown
future schemas
- self-heal recoverable CLI key metadata and use canonical `blake3:<64
lowercase hex>` fingerprints across kernel, gateway, audit, and
MCP-owned surfaces
- stop logging dictionary-testable hashes of low-entropy environment
values
- publish `BLAKE3SUMS.txt` as the primary Astrid release-integrity
manifest while retaining signed and attested `SHA256SUMS.txt` for
released clients, Homebrew, and downstream compatibility
- strictly reject malformed, duplicate, uppercase, missing, mismatched,
SHA-only, and overlong manifest entries
- authenticate release archives with fresh production Sigstore TUF
metadata, the exact Astrid release workflow/tag identity, and the GitHub
Actions issuer before integrity verification or extraction
- keep publisher-authentication, integrity, and preparation failures as
typed stages, preserving exact asset-selection failure causes
- preserve empty credential-store reads on read-only deployments while
keeping non-empty legacy SHA invalidation mandatory
- run Cosign and the native production verifier over every
archive/bundle pair before release publication
- document the identifier, release-integrity, publisher-authentication,
and compatibility boundaries

External SHA contracts such as SRI, Git object formats, Cargo registry
checksums, Sigstore/SLSA internals, and Homebrew formula fields remain
unchanged.

## Verification

- exact signed head: `c44a3908aa3e34611540e5d82331171e218940ae`
- exact base: merged `main` at
`122725708f6b58d3c77c1dc4df4763f345d94c3e`
- all 20 commits from the base verify as Good GPG signatures
- full Astrid CLI unit suite: 493 passed, 1 intentional release-gate
test ignored
- publisher-authentication suite: 10 passed, 1 intentional live
release-gate test ignored
- self-update suite: 15 passed
- full kernel suite: 281 passed
- complete affected-package matrix previously passed for CLI, core,
crypto, gateway, kernel, and MCP
- strict all-target/all-feature Clippy passed for the CLI and all
affected identifier packages
- `cargo fmt --all -- --check`
- `cargo metadata --locked --no-deps --format-version 1`
- `git diff --check`
- `actionlint .github/workflows/release.yml`
- BLAKE3 derive-key vectors independently reproduced with `b3sum
--derive-key`
- independent security reviews found no unresolved correctness or
security issue; the final exact consolidated head is being re-reviewed

## Checklist

- [x] Linked to issues
- [x] CHANGELOG.md updated under `[Unreleased]`

No release is created or published by this change.
@joshuajbouw

Copy link
Copy Markdown
Contributor Author

Superseded by and landed through #1254. The merged squash commit a1d4e65 contains this complete signed BLAKE3 identifier and compatibility work together with the coordinated release-integrity and publisher-authentication stack.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace Astrid-owned SHA-256 identifiers with domain-separated BLAKE3

2 participants