CredTrail self-hosting lifecycle and recovery evidence review Reviewed: October 5, 2026 Publisher: Longsight Repository: https://github.com/LongsightGroup/credtrail-app Commit: d8230519af8f5ea5860c328f7ead2071c926dbd1 Runbook: https://github.com/LongsightGroup/credtrail-app/blob/d8230519af8f5ea5860c328f7ead2071c926dbd1/docs/SELF_HOST_DOCKER_RUNBOOK.md Environment and scope - Fresh checkout of the public revision above; no application source changes. - Docker 29.4.0 on macOS, using a local OrbStack runtime. - Production Dockerfile with Node.js 24 and pnpm 10.29.2 locked installation. - Separate API and queue-worker containers, Postgres 17, local S3-compatible gofakes3 storage, nginx 1.29 with a generated local TLS certificate, and the repository's local SMTP fixture with STARTTLS and a test trust certificate. - Generated test identities, keys, secrets, domains, database and buckets only. No institutional records, cloud credentials, or real outbound email. Reproduction Use a fresh checkout of the fixed public revision. Install locked dependencies and build the production image: pnpm install --frozen-lockfile docker build --tag credtrail-seo-d8230519:local . The existing scripts/selfhost-production-smoke.mjs runs the production runtime, storage, queue, credential lifecycle, independent signature checks, and SMTP checks. The recovery extension used in this review is available at: https://www.longsight.com/downloads/credtrail-selfhost-recovery-check-2026-10-05.mjs Place that accompanying file in scripts/ in the same disposable checkout. Add this import to scripts/selfhost-production-smoke.mjs: import { checkSelfhostRecovery } from './credtrail-selfhost-recovery-check-2026-10-05.mjs'; Immediately after the existing await smtp.verifyIssuance(...) call, before the final success log, add: await checkSelfhostRecovery({ docker, prefix, network, image, directory, values, smtp, start, poll, http, origin, row, credential, publicKeyMultibase, extension, }); Run the instrumented harness from the repository root: pnpm exec node scripts/selfhost-production-smoke.mjs --image credtrail-seo-d8230519:local This helper is tied to the reviewed harness and its generated test resources. Never pass production credentials, containers, databases, buckets, or domains. The harness cleans its disposable containers, network, and temporary backups on completion; the separately built application image remains available. Observed lifecycle results - Production API and worker readiness, discovery and stored-object contracts: passed against the real local Postgres and S3-compatible dependencies. - Programmatic issuance: request accepted, queue job completed, public signed credential available, active proof verification passed. - Independent signature verification: passed using the repository's separate Digital Bazaar/jsonld-signatures verification script, not the app verifier. - Idempotent replay: same issued identity returned without duplicate issuance. - Revocation: queue job completed; public verification reported revoked status. - SMTP fixture: packaged no-send mode, actual test sign-in delivery, and issuance delivery acceptance/rejection audit and retry checks passed. - Existing harness HTTP policy, CSRF, login-asset and forged-header checks passed. These do not constitute a complete security assessment. Observed recovery results - Stopped the worker and API before taking the database backup; captured all three stored objects and their content types, cache settings and metadata. - Saved a custom-format Postgres dump, object data, and generated operator settings as local recovery artifacts. Object/settings files used mode 0600. - Restored the saved dump into a new database, not over the original database. - Restored all three objects into a new bucket. Their bytes and metadata matched the originals; the saved database dump's SHA-256 hash was unchanged. - Started the same production image using the restored database, bucket and backed-up test operator settings. Dependency readiness passed. - Retrieved the same credential from the same local public URL. Its signed JSON-LD matched the pre-backup credential and independent signature verification passed. Its public page returned HTTP 200, and verification still reported revoked status. Recovery email was disabled. The first recovery attempt could not reach readiness because the new test helper replaced a database name in the connection URL incorrectly. The helper was corrected to change the URL pathname. The complete unchanged application lifecycle plus corrected recovery exercise then passed. This was a review harness error, not a demonstrated application failure. Limits and institutional follow-up - This was local recovery into a separate database on the same Postgres server and a separate bucket on the same S3 emulator. It was not recovery after loss of a host, cloud account, region, provider, or institution's key store. - Actual AWS RDS, S3, R2, SES, institutional SMTP and public DNS/certificates were not exercised. A test relay does not establish inbox delivery or an institution's SPF, DKIM, DMARC, sender identity, or mail-retention compliance. - The local HTTPS client ignored certificate errors for the generated test certificate. This does not validate a production certificate chain. SMTP used the fixture trust certificate to validate its local STARTTLS connection. - Operator secrets and signing material were generated for this test. A real deployment needs protected backup storage, key custody, recovery authority, rotation, access review and a separately approved retention policy. - The exercise did not measure recovery-time or recovery-point objectives, scale, load, uptime, accessibility, or disaster isolation. It did not reconcile every approval or audit record, although the database dump restored. - Independent cryptographic verification here used a separate library in the harness. It was not acceptance by another credential product or a 1EdTech certification test. No certification claim follows from these results. - Run the lifecycle and recovery acceptance tests again in the institution's intended operating environment, with its domain-continuity and exit plan. Pinned source references Base URL: https://github.com/LongsightGroup/credtrail-app/blob/d8230519af8f5ea5860c328f7ead2071c926dbd1/ - Dockerfile - docs/SELF_HOST_DOCKER_RUNBOOK.md - scripts/selfhost-production-smoke.mjs - scripts/fixtures/selfhost-smtp-smoke.mjs - scripts/fixtures/selfhost-smtp-relay.mjs - scripts/verify-credential-interoperability.mjs Institutional worksheet: https://www.longsight.com/downloads/digital-credential-evaluation-worksheet.txt