Skip to content

Commit 4f423a6

Browse files
committed
Prepare 1.0.3
1 parent 49649b5 commit 4f423a6

10 files changed

Lines changed: 193 additions & 48 deletions

File tree

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,18 @@ jobs:
2525

2626
steps:
2727
- name: Checkout repository
28-
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
28+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
2929

3030
- name: Install Rust toolchain
3131
run: rustup show
3232

3333
- name: Cache Rust build output
34-
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
34+
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
3535
with:
3636
cache-on-failure: true
3737

3838
- name: Install security tools
39-
uses: taiki-e/install-action@873c7452cadb7c034694a1282227095d93fbdf92 # v2.79.14
39+
uses: taiki-e/install-action@0631aa6515c7d545823c67cfae7ef4fc7f490154 # v2.81.8
4040
with:
4141
tool: cargo-deny,cargo-audit
4242

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
# Changelog
22

3+
## 1.0.3
4+
5+
- Bumped the crate to `1.0.3`.
6+
- Hardened encoded-output error paths by keeping encoder output in a
7+
`Zeroizing<Vec<u8>>` until successful return, so partially encoded bytes are
8+
scrubbed on encoder errors.
9+
- Added debug/test assertions for exact identity, cache-key, and XXH3 chunk
10+
preimage capacities so future edits cannot silently introduce reallocations
11+
before zeroization.
12+
- Redacted `AvatarBuilder` namespace tenant and style-version values from
13+
`Debug` output in addition to the identity input.
14+
- Updated `docs/SECURITY_CONTROLS.md` to accurately describe accepted
15+
upper-digest-byte visual parameter usage for `1.x` visual stability.
16+
- Updated GitHub Actions pins to `actions/checkout` `v6.0.3`,
17+
`Swatinem/rust-cache` `v2.9.1`, and `taiki-e/install-action` `v2.81.8`.
18+
- Removed the temporary pentest report from the tree.
19+
320
## 1.0.2
421

522
- Bumped the crate to `1.0.2`.

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "hashavatar"
3-
version = "1.0.2"
3+
version = "1.0.3"
44
edition = "2024"
55
rust-version = "1.90"
66
description = "Stable deterministic procedural avatars in Rust with configurable identity hashing, WebP, optional PNG/JPEG/GIF, and SVG export"

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ The crate starts conservative: validated avatar dimensions, bounded identity inp
2929

3030
## Current Status
3131

32-
The current crate version is `1.0.2`.
32+
The current crate version is `1.0.3`.
3333

3434
Implemented now:
3535

@@ -106,7 +106,7 @@ to split it.
106106
The minimum supported Rust version is Rust `1.90.0`. New deployments should
107107
prefer the latest stable Rust; as of May 29, 2026, that is Rust `1.96.0`.
108108

109-
Compatibility evidence for `1.0.2`:
109+
Compatibility evidence for `1.0.3`:
110110

111111
| Rust | Local Evidence |
112112
| --- | --- |
@@ -127,36 +127,36 @@ Optional hash modes are mutually exclusive, so `hashavatar` cannot use a single
127127

128128
```toml
129129
[dependencies]
130-
hashavatar = "1.0.2"
130+
hashavatar = "1.0.3"
131131
```
132132

133133
Optional identity hash modes and extra raster encoders are disabled by default.
134134
Hash modes are mutually exclusive, so enable at most one of `blake3` or `xxh3`:
135135

136136
```toml
137137
[dependencies]
138-
hashavatar = { version = "1.0.2", features = ["blake3"] }
138+
hashavatar = { version = "1.0.3", features = ["blake3"] }
139139
```
140140

141141
Enable additional raster formats explicitly:
142142

143143
```toml
144144
[dependencies]
145-
hashavatar = { version = "1.0.2", features = ["png", "jpeg", "gif"] }
145+
hashavatar = { version = "1.0.3", features = ["png", "jpeg", "gif"] }
146146
```
147147

148148
Or enable every optional raster encoder at once:
149149

150150
```toml
151151
[dependencies]
152-
hashavatar = { version = "1.0.2", features = ["all-formats"] }
152+
hashavatar = { version = "1.0.3", features = ["all-formats"] }
153153
```
154154

155155
Enable string serialization/deserialization for public style enums:
156156

157157
```toml
158158
[dependencies]
159-
hashavatar = { version = "1.0.2", features = ["serde"] }
159+
hashavatar = { version = "1.0.3", features = ["serde"] }
160160
```
161161

162162
Combine these as needed, for example `features = ["blake3", "png", "serde"]`.
@@ -519,7 +519,7 @@ your namespace style version when intentionally migrating output.
519519

520520
```toml
521521
[dependencies]
522-
hashavatar = { version = "1.0.2", features = ["blake3"] }
522+
hashavatar = { version = "1.0.3", features = ["blake3"] }
523523
```
524524

525525
```rust
@@ -547,7 +547,7 @@ assert!(svg.contains("alien avatar"));
547547

548548
```toml
549549
[dependencies]
550-
hashavatar = { version = "1.0.2", features = ["xxh3"] }
550+
hashavatar = { version = "1.0.3", features = ["xxh3"] }
551551
```
552552

553553
```rust

docs/SECURITY_CONTROLS.md

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,12 @@
3434
`hashavatar` cannot zeroize those codec-owned buffers. High-assurance
3535
deployments should prefer WebP or PNG.
3636
- Procedural RNG seeding uses 256 bits from the second half of the identity
37-
digest, separate from the lower digest bytes commonly used for direct visual
38-
parameters.
37+
digest. Most direct visual parameter lookups use lower digest bytes, but some
38+
established renderers also use selected upper digest bytes for visible
39+
geometry. This is accepted for `1.x` visual stability: avatars are
40+
digest-derived public artifacts, and removing those lookups would change
41+
golden output. Callers that treat identifiers as sensitive should prefer
42+
SHA-512 or BLAKE3 over XXH3 and follow the timing/output-size guidance below.
3943
- The temporary 256-bit RNG seed copy is stored in `zeroize::Zeroizing`, so the
4044
digest-derived seed copy is scrubbed on scope exit. The final value passed to
4145
`StdRng::from_seed` is also held in a `Zeroizing` guard before the copy into
@@ -53,7 +57,8 @@
5357
- `AvatarIdentity` has a redacted `Debug` implementation so accidental
5458
`{:?}` logging does not print the raw digest.
5559
- `AvatarBuilder` has a redacted `Debug` implementation so accidental builder
56-
logging does not print the raw identity input.
60+
logging does not print the raw identity input, tenant, or style-version
61+
namespace values.
5762
- `AvatarIdentity::cache_key()` derives an opaque display key by hashing the
5863
internal identity digest under a cache-key domain instead of returning raw
5964
digest bytes. Cache keys are still stable correlators for the same identity
@@ -75,11 +80,13 @@
7580
BLAKE3 hasher and XOF reader after deriving the 64-byte digest. Tests assert
7681
these upstream zeroization traits remain available.
7782
- Identity hash preimage allocation is sized from the tenant, style-version,
78-
and identity input lengths. The crate bounds and zeroizes those temporary
79-
buffers, but it does not hide input length from the allocator, OS-level heap
80-
profilers, or other same-process memory-observation tools. Very
81-
high-assurance callers that treat identifier length as sensitive should
82-
normalize or pad identifiers to a fixed length before calling this crate.
83+
and identity input lengths. Debug/test builds assert that preimage buffers do
84+
not reallocate before zeroization, so future component-size drift is caught by
85+
CI. The crate bounds and zeroizes those temporary buffers, but it does not
86+
hide input length from the allocator, OS-level heap profilers, or other
87+
same-process memory-observation tools. Very high-assurance callers that treat
88+
identifier length as sensitive should normalize or pad identifiers to a fixed
89+
length before calling this crate.
8390
- The optional XXH3-128 mode derives the crate's 64-byte identity digest by
8491
hashing four domain-separated chunks. Each chunk temporarily copies the
8592
bounded preimage into a zeroized buffer, so peak preimage memory is higher
@@ -93,7 +100,9 @@
93100
binary must configure and test `getrandom` for their target explicitly.
94101
- Encode APIs wrap temporary owned raster buffers in RAII zeroization guards, so
95102
pixel data is cleared during normal returns, encoder errors, and unwinding
96-
panics. JPEG export also wraps the temporary RGB flattening buffer in
103+
panics. Encoded output is accumulated in a `Zeroizing<Vec<u8>>` until
104+
successful return, so partially encoded bytes are scrubbed on encoder errors.
105+
JPEG export also wraps the temporary RGB flattening buffer in
97106
`zeroize::Zeroizing`. Returned encoded bytes and images returned by render
98107
APIs are caller-owned and must be cleared by the caller if their environment
99108
requires that. The README includes `zeroize` examples for returned `Vec<u8>`
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# hashavatar 1.0.3
2+
3+
`1.0.3` is a security-hardening and CI maintenance release for `hashavatar`.
4+
5+
## Security And Hardening
6+
7+
- Encoded output is now accumulated in a `Zeroizing<Vec<u8>>` until successful
8+
return. If an encoder returns an error after writing partial bytes, those
9+
partially encoded bytes are scrubbed before being dropped.
10+
- Identity, cache-key, and XXH3 chunk preimage builders now assert exact
11+
capacity in debug/test builds. This catches future component-size drift that
12+
would otherwise allow reallocations before zeroization.
13+
- `AvatarBuilder` debug output now redacts namespace tenant and style-version
14+
values, not only the raw identity input.
15+
- Security controls now document the accepted `1.x` visual-stability tradeoff
16+
that some established renderers use selected upper digest bytes directly for
17+
visible geometry.
18+
19+
## CI
20+
21+
- Updated pinned GitHub Actions:
22+
- `actions/checkout` to `v6.0.3`
23+
- `Swatinem/rust-cache` to `v2.9.1`
24+
- `taiki-e/install-action` to `v2.81.8`
25+
26+
## Compatibility
27+
28+
- No intentional avatar visual fingerprint changes.
29+
- No public API removals.
30+
- No dependency version changes.

fuzz/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fuzz/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ publish = false
88
cargo-fuzz = true
99

1010
[dependencies]
11-
hashavatar = { path = "..", version = "1.0.2", features = ["fuzzing"] }
11+
hashavatar = { path = "..", version = "1.0.3", features = ["fuzzing"] }
1212
libfuzzer-sys = "0.4"
1313
roxmltree = "0.21.1"
1414

0 commit comments

Comments
 (0)