External member smoke

Prove authenticated member paths through the real public edge.

This harness runs from outside the VPS against the final HTTPS origin with a disposable member created by an operator-only provisioning command. It verifies login, account posture, library/media access, byte-range delivery, explicit download policy, non-authoritative checkout returns, and owner gate exposure without printing recovery secrets.

Provision

Create the disposable member on the VPS

# Run with the intended VPS environment loaded and the key directory already created.
cargo run -- smoke-member-provision \
  --recovery-key-file /secure/operator/nocturne-smoke-recovery-key.txt \
  --source-reference external-member-smoke-YYYYMMDD

The provision command creates one age-attested member, confirms recovery custody immediately, grants a short manual thirty_day_pass by default, and prints the exact external smoke command with the generated member ID. It stores no email, raw IP address, user-agent, ID document, or plaintext recovery key.

Secret handling: prefer --recovery-key-file. The file must not already exist, is written with 0600 permissions on Unix, and should be copied only through the operator's secure channel. --allow-stdout-key exists only as an explicit disposable-test escape hatch.
Command

Run after the public edge smoke and provisioning pass

chmod 600 /secure/operator/nocturne-smoke-recovery-key.txt

NOCTURNE_PUBLIC_ORIGIN=https://members.final-domain.example \
NOCTURNE_SMOKE_MEMBER_ID=nctm_disposable_member \
NOCTURNE_SMOKE_RECOVERY_KEY_FILE=/secure/operator/nocturne-smoke-recovery-key.txt \
  make external-member-smoke

The script also accepts the origin as its first argument. The recovery key should come from a local file whenever possible so it does not land in shell history. Environment fallback exists for private disposable tests, and NOCTURNE_SMOKE_RECOVERY_KEY_STDIN=1 can read one piped line.

Disposable member only: this smoke creates an authenticated session and a provider-neutral checkout session, marks the checkout browser-success return, checks owner posture, then attempts to log out. Use an account created only for VPS validation and clean up its active access afterwards.
Prerequisites

What must exist before running it

The local seed helper remains local-profile-only. Use smoke-member-provision for private VPS validation because it is non-destructive, writes the generated recovery key to an operator file by default, and grants only short-lived smoke access.

Coverage

What the member smoke proves

CheckExpected resultWhy it matters
/loginLogin form renders, disposable credentials authenticate, and a session cookie is accepted through the proxy.Confirms secure-cookie/browser session posture works at the final origin.
/accountPrivate account page renders with recovery-confirmed posture.Confirms self-custody recovery confirmation gates member-only access as intended.
/libraryPreview entitlement and the expected fixture media link render.Confirms entitlement checks survive external HTTPS routing.
/media/asset_preview_still_001Media detail page exposes inline viewer and explicit download affordance.Confirms member media is gated through app routes rather than public files.
/media/.../file with Range: bytes=0-9206, Content-Range, and Accept-Ranges.Confirms video-friendly byte-range delivery works through the proxy without reading whole files into memory.
/media/.../download with range206 plus attachment Content-Disposition.Confirms download policy stays explicit and separate from inline viewing.
/checkout, /checkout/start, success returnCheckout session is created, success route renders, and browser return stays non-authoritative.Confirms the provider-neutral checkout skeleton cannot grant access without provider-proof replay.
/ownerDisabled, unauthorized, or non-dashboard gate body; never an unlocked owner surface without auth.Confirms private review tools are not accidentally exposed at the public edge.
/logoutThe smoke session is closed at the end.Keeps disposable external testing from accumulating live browser sessions.
Failure interpretation

What to fix first

Cleanup

After a passing smoke

cargo run -- smoke-member-cleanup \
  --member-id nctm_disposable_member \
  --confirm-smoke-member-cleanup

rm -f /secure/operator/nocturne-smoke-recovery-key.txt
cargo run -- payment-checkout-expire
  1. Run smoke-member-cleanup for the disposable member. It revokes active entitlements and active sessions, but keeps pseudonymous records for audit continuity.
  2. Delete the local recovery-key file from the operator workstation or move it back to the sealed credentials store.
  3. Expire stale checkout sessions with payment-checkout-expire before wider private testing.
  4. Record the date, origin, app commit, proxy type/version, and pass/fail output through deployment-evidence-record with artifact hashes instead of pasted logs or recovery secrets.
  5. Run production-preflight locally on the VPS again after any proxy/app changes, record sealed backup dump/media hashes with backup-manifest-record, record encrypted/offsite custody with backup-custody-record, then run private-vps-readiness before widening private testing.
Limits

What this smoke does not prove