Skip to content

Commit a30c6f6

Browse files
committed
Finalize hashavatar-api 1.1.2 release candidate
1 parent b7a6490 commit a30c6f6

11 files changed

Lines changed: 52 additions & 18 deletions

CLOUDFLARE.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,24 @@ If you want stricter cache deduplication:
6767

6868
- normalize query ordering at the application layer
6969
- prefer canonical URLs in clients
70-
- keep `id`, `kind`, `background`, `format`, `size` only
70+
- include every rendering parameter in the cache key: `id`, `tenant`,
71+
`style_version`, `algorithm`, `kind`, `background`, `accessory`, `color`,
72+
`expression`, `shape`, `format`, and `size`
7173
- prefer the path API when you want the cleanest cache key shape
7274

7375
## 7. Why this is safe to cache hard
7476

7577
The avatar response is deterministic for the full request tuple:
7678

7779
- identity
80+
- tenant and style version
81+
- algorithm
7882
- kind
7983
- background
84+
- accessory
85+
- color
86+
- expression
87+
- shape
8088
- format
8189
- size
8290

DEPLOYMENT-HETZNER.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,11 @@ podman-compose up -d --build
7575
## Notes
7676

7777
- Fluxheim listens publicly on `80` and `443`
78+
- the Compose example pins the Fluxheim `1.7.6` Wolfi image by digest
7879
- the Rust app stays internal on port `8080`
80+
- both containers have CPU, memory, PID, and file-descriptor ceilings
7981
- `HASHAVATAR_TRUSTED_PROXIES` is set to the private Compose network so the app
8082
only honors forwarded client IP headers from Fluxheim
8183
- if Cloudflare is in front, keep DNS proxied and apply the cache rules from [`CLOUDFLARE.md`](./CLOUDFLARE.md)
8284
- the avatar endpoints are deterministic, so they are safe to cache hard at the edge
85+
- do not add a public Fluxheim route for the loopback-only `/metrics` endpoint

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ RUN cargo build --release \
1010
&& rm -rf target /usr/local/cargo/registry /usr/local/cargo/git
1111

1212
FROM cgr.dev/chainguard/wolfi-base:latest@sha256:02dab76bd852a70556b5b2002195c8a5fdab77d323c433bf6642aab080489795
13-
RUN apk add --no-cache ca-certificates glibc \
14-
&& addgroup -S appuser \
13+
RUN addgroup -S appuser \
1514
&& adduser -S -D -H -u 10001 -G appuser appuser
1615
WORKDIR /app
1716

17+
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
1818
COPY --from=build /usr/local/bin/hashavatar-api /usr/local/bin/hashavatar-api
1919

2020
ENV PORT=8080

PROVENANCE.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ This repository serves avatars generated by the `hashavatar 1.1.2` Rust crate.
1313

1414
- Identity input is hashed with `SHA-512`.
1515
- Digest bytes are mapped into visual parameters such as proportions, colors, spacing, and facial details.
16-
- Final images are rendered using drawing primitives provided by Rust crates such as `image` and `imageproc`.
16+
- Final images are rendered using the `hashavatar` crate and encoded through
17+
the Rust `image` ecosystem.
1718

1819
## Current avatar families
1920

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,15 @@ Intentionally external:
7777
| Renderer crate | crates.io `hashavatar 1.1.2` |
7878
| MSRV | Rust `1.97.0` |
7979
| Runtime container | Wolfi |
80+
| Gateway example | Fluxheim `1.7.6` Wolfi image, digest-pinned |
8081
| HTTP framework | `axum` |
8182
| Object storage | Optional S3-compatible backend |
8283
| Rate limiter | Bounded LRU map |
8384
| Forwarded IP policy | Trusted proxies only |
8485
| Internal errors | Detailed logs, generic client body |
8586
| Security headers | CSP, permissions policy, referrer policy, `nosniff`, frame denial, CORP, COOP, HSTS |
8687
| Release evidence | fmt, metadata, docs, clippy, tests, deny, audit, smoke, SBOM, reproducibility |
88+
| Release inputs | Actions and container images pinned to immutable revisions |
8789
| Code scanning | GitHub CodeQL default setup |
8890

8991
Security-control details live in
@@ -429,10 +431,11 @@ The repository includes:
429431
- Markdown link checks
430432
- security invariant checks
431433
- clippy with warnings denied
432-
- unit tests for rate limiting, trusted proxy handling, renderer validation,
433-
and internal error disclosure behavior
434+
- unit tests for rate limiting, trusted proxy handling, body limits, transport
435+
validation, renderer validation, cache keys, and internal error disclosure
434436
- local HTTP smoke tests for health, WebP rendering, security headers,
435-
unsupported algorithm/format rejection, and invalid namespace rejection
437+
S3-enabled startup, unsupported algorithm/format/style rejection, oversized
438+
body rejection, and invalid namespace rejection
436439
- local Podman smoke tests for the Wolfi image when
437440
`HASHAVATAR_API_GATE_PODMAN=1` is set
438441
- `cargo deny` dependency and license policy

THIRD_PARTY_NOTICES.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
# Third-Party Notices
22

3-
Portions of the raster drawing primitives in `src/lib.rs` are adapted from
4-
`imageproc` drawing modules.
3+
This service does not vendor third-party source or avatar artwork. Rust
4+
dependencies and their licenses are tracked by `Cargo.lock`, `cargo deny`, and
5+
the SPDX and CycloneDX SBOMs generated by `scripts/generate-sbom.sh`.
6+
7+
The procedural renderer is provided by the separately published `hashavatar`
8+
crate. Renderer-specific source attribution and notices are maintained in its
9+
upstream repository. The linked renderer contains raster primitives adapted
10+
from `imageproc`; its required notice is reproduced below.
511

612
## imageproc
713

deploy/README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ It runs two containers on one private network:
55

66
- `hashavatar`: builds this repository with the Wolfi runtime image from
77
`../Dockerfile` and listens internally on port `8080`.
8-
- `fluxheim`: runs `ghcr.io/valkyoth/fluxheim:v1.6.30-wolfi`, publishes ports
8+
- `fluxheim`: runs the digest-pinned
9+
`ghcr.io/valkyoth/fluxheim:v1.7.6-wolfi` image, publishes ports
910
`80` and `443`, terminates TLS, redirects HTTP to HTTPS, redirects
1011
`www.hashavatar.app` to `hashavatar.app`, and proxies traffic to
1112
`hashavatar:8080`.
@@ -26,6 +27,10 @@ tmpfs, and CPU, memory, PID, and file-descriptor ceilings. Fluxheim has separate
2627
resource ceilings. Tune these values with production load tests rather than
2728
removing them.
2829

30+
The deployment image, build image, runtime image, and GitHub actions are pinned
31+
to immutable revisions. The Wolfi runtime does not download packages during the
32+
build; its CA bundle is copied from the pinned Rust builder.
33+
2934
Both Fluxheim and Axum reject request bodies larger than `4KiB`; the public API
3035
uses request bodies only for small, bounded telemetry events.
3136

deploy/podman-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ services:
3333
- hashavatar
3434

3535
fluxheim:
36-
image: ghcr.io/valkyoth/fluxheim:v1.6.30-wolfi
36+
image: ghcr.io/valkyoth/fluxheim:v1.7.6-wolfi@sha256:462b98287a0eb0e405cd302b818c5bab0507e18845191eb0abe3732bfd953477
3737
container_name: hashavatar-fluxheim
3838
restart: unless-stopped
3939
cpus: 2.0

docs/SECURITY_CONTROLS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ local test and release gates.
2121
| PII in infrastructure logs | Email-shaped identities are accepted for compatibility; callers who want less personal data in URL logs should send opaque stable ids or one-way hashes. |
2222
| Vulnerable or incompatible dependencies | `cargo audit` and `cargo deny check` run in the standard check script and CI. |
2323
| Plaintext backend transport | Remote OTLP and custom S3 endpoints require HTTPS. HTTP is accepted only for loopback-local development endpoints, and the application enables explicit Rustls-backed clients for both integrations. |
24-
| Mutable release inputs | GitHub actions and Docker base images are pinned to reviewed commit SHAs and image digests. Dependabot tracks Cargo, action, and Docker updates; image publishing emits SBOM and maximum provenance attestations. |
24+
| Mutable release inputs | GitHub actions, Docker base images, and the Fluxheim deployment image are pinned to reviewed commit SHAs and image digests. The runtime image does not install from a live package repository; its CA bundle comes from the pinned builder. Dependabot tracks Cargo, action, and Docker updates; image publishing emits SBOM and maximum provenance attestations. |
2525

2626
## Self-Testing
2727

release-notes/RELEASE_NOTES_1.1.2.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# hashavatar-api 1.1.2 Release Notes
22

3-
Status: draft
3+
Status: release candidate
44

55
## Summary
66

77
`1.1.2` is the next stable patch release for the API, renderer dependency,
88
Rust toolchain, dependency graph, and CI tooling.
99

10-
These notes are based on the current working tree and should be rechecked
11-
against the final tag before publishing.
10+
These notes describe the release candidate and should be checked against the
11+
final tag before publishing.
1212

1313
## Changed
1414

@@ -33,12 +33,14 @@ against the final tag before publishing.
3333
- Hardened embedded JSON, drawing arithmetic, and object-key identity hashing.
3434
- Pinned GitHub actions and container bases to immutable revisions, enabled
3535
image SBOM/provenance attestations, and added deployment resource ceilings.
36+
- Pinned the Fluxheim deployment image and removed live APK package installation
37+
from the runtime image build.
38+
- Updated the digest-pinned Fluxheim Wolfi deployment image to `v1.7.6`.
3639

3740
## Verification
3841

3942
```bash
4043
cargo outdated --workspace --root-deps-only
41-
scripts/checks.sh
42-
scripts/smoke_local.sh
43-
scripts/podman_smoke.sh
44+
HASHAVATAR_API_GATE_PODMAN=1 scripts/stable_release_gate.sh check
45+
podman compose -f deploy/podman-compose.yml config
4446
```

0 commit comments

Comments
 (0)