openalice-passport
Architecture rating
JWT-gated issue/revoke with AuthUser extractor; RLS FORCE + owner-scoped INSERT/UPDATE policies on passports; per-owner rate limit (600 rpm default); injection-safe set_config($1,true) for owner context; 0600 keyfile enforcement with permission check on load; cargo-deny gates RustSec advisories + copyleft + untrusted sources; dev-secret boot guard panics in non-dev; set_security_headers + normalize_errors middleware; internal error detail never leaked to client; OS CSPRNG only (getrandom). Minor: jwt_secret held as plain String in AppState (not zeroized like the SigningKey scalar).
Uniform adoption of openalice-axum-common: AuthUser/JwtVerifier, CORS, rate_limit, security_headers, normalize_errors, http_metrics, tracing init, shutdown_signal, internal_client. Middleware stack order documented as identical to vault/tenants. RLS owner-context pattern (with_owner_context + SET LOCAL) matches vault. Canonical JSON + BLAKE3 ported verbatim from vault (documented byte-identical). Same cargo-deny + Docker BuildKit pattern. Minor: dual error types (AppError in error.rs + ApiError in api/mod.rs); 4 god modules flagged by inspector.
40 tests across 7 modules: 13 VC crypto tests covering every tamper vector (subject id, component, manifest_hash, provenance, vault_version, issuer, proof metadata, wrong key, missing proof) + determinism + JSON roundtrip; 4 DB-gated acceptance tests (full issue→verify→revoke lifecycle, RLS cross-owner isolation, unknown-id 404, tampered-stored-credential detection); 4 router wire tests (auth gating on issue/revoke, public verify reachability, health mount); 6 boot-guard tests; 6 signing tests incl. 0600 keyfile enforcement; 4 canon tests (float rejection, BLAKE3 stability). No coverage metrics; CI status unknown.
Single clean migration with CHECK constraint on component enum; 3 RLS policies (public SELECT USING(true), owner INSERT WITH CHECK, owner UPDATE USING+WITH CHECK) correctly model asymmetric trust; idempotent FORCE RLS toggle helpers; with_owner_context uses SET LOCAL (tx-scoped, no pool leakage); UUIDv7 PKs; indexes on identity_id + owner_user_id; revoked_at nullable pattern. No FKs (documented intentional denormalization). No GDPR purge mechanism visible; manifest_owns_tables empty in Atlas.
Graceful shutdown via axum with_graceful_shutdown(shutdown_signal()) on SIGTERM; pool acquire_timeout 5s with 4..20 connections; idempotent RLS toggle + idempotent revocation (re-revoke returns false, not error); boot-guard pattern: missing signing key → 503 for passport ops while /health stays up; kill switch (off/on/shadow) for incident-response hard stop. No circuit breaker, no retry logic, no per-request timeout middleware visible.
Prometheus recorder installed at boot with /metrics endpoint; track_http_metrics middleware on all routes; init_tracing with EnvFilter + OTEL guard; TraceLayer (INFO spans); propagate_incoming for distributed trace context; structured tracing::info/warn/error throughout (key fingerprint, RLS state, rate limit config at boot); /health returns JSON with deps.postgres status. No domain-specific counters (passports_issued_total, verifications_total); no readiness vs liveness distinction.
Extensive in-code architecture docs: every module has //! doc blocks explaining the trust model, signed surface recipe, and RLS asymmetry; migration file heavily commented with policy rationale; Cargo.toml annotates every dep group (security justification for sqlx default-features=false); deny.toml thoroughly commented; @feature annotations in lib.rs + main.rs. No README (Atlas readme_excerpt empty); no manifest file (manifest_present=false); no OpenAPI spec; no CHANGELOG.
source · auto-grader-2026-06-17
Code composition
tokei · loc- Rust92.8%
- TOML4.5%
- SQL1.6%
- Dockerfile1.1%
- Rust92.8%
- TOML4.5%
- SQL1.6%
- Dockerfile1.1%
- Rust92.8%· 2,087
- TOML4.5%· 102
- SQL1.6%· 37
- Dockerfile1.1%· 24
| Language | % code | code | comments | blanks | files |
|---|---|---|---|---|---|
| Rust | 92.8% | 2,087 | 110 | 263 | 21 |
| TOML | 4.5% | 102 | 78 | 12 | 2 |
| SQL | 1.6% | 37 | 52 | 10 | 1 |
| Dockerfile | 1.1% | 24 | 19 | 12 | 1 |
Telemetry ribbon · last 90 days
3 eventspassport/crate
1 feature- passport.crate.passport-authoritysrc/lib.rs:4Rust/Axum service (port 3993) that ISSUES W3C Verifiable Credentials (one per soul component — soul/memory/voice/visual/genome), each carrying an Ed25519 proof over the canonical credential, and serves a PUBLIC, signed-Postgres verification registry (the "CA/DNS for digital identity"). Also issues a minimal, HONEST C2PA-style export attestation (a deterrent + compliance artifact, NOT technical enforcement — strippable on transcode). NO blockchain / tokens — a signed Postgres registry only (Build Spec §7). ## Trust model (asymmetric) * **Issuance + revocation are owner-scoped** — Postgres Row-Level Security keyed on `app.owner_id` (see [`db`]); the app role MUST be NOSUPERUSER NOBYPASSRLS for FORCE RLS to bite (applied at boot via `PASSPORT_RLS_ENFORCE`). * **Verification is PUBLIC** — a permissive `FOR SELECT USING (true)` policy lets anyone verify a passport by id with NO owner context, against the issuer's public key. ## The signed crypto surface (audit this first) Every signature (VC proof + C2PA attestation) is Ed25519 over `blake3(canonical_json(payload_with_signature_field_blanked))`. The canonical form is float-free + key-sorted and byte-identical to the vault's ([`crypto::canon`]). See [`vc`] + [`c2pa`] module docs for the exact recipe.
passport/middleware
1 feature- passport.middleware.rate-limitsrc/main.rs:3Per-owner token-bucket rate limiter on the JWT-gated issue/revoke surface (default 600 req/min ≈ 10 RPS, overridable via PASSPORT_RATE_LIMIT_PER_MINUTE). The PUBLIC verify route is NOT rate-limited per-owner (it has no owner); it rides the shared middleware only. Provided by openalice-axum-common::rate_limit. default-rpm: 600 Routes: * `/health` — Traefik liveness probe. * `/metrics` — Prometheus scrape. * `GET /v1/passports/{pid}/verify` — PUBLIC credential verification. * `POST /v1/identities/{id}/passports` — issue (JWT-gated). * `POST /v1/passports/{pid}/revoke` — revoke (JWT-gated).