Skip to content

Veteran onboarding SOP (last1.app + Last1 ID)

Audience: Partner organizations onboarding veterans through last1.app
Purpose: Repeatable, org-agnostic process any veteran-serving org can follow without Last1 hand-holding
Surfaces: last1.app (member portal) + auth.last1.id (verification) + LastVet iOS (coordination read, when enrolled)


When this SOP applies

Use this flow when [Org] requires veteran verification before program milestones:

  • organizations.requires_veteran_verification = true, or
  • Org bundle tier starts with vso_* (VSO bundle auto-triggers the same policy)

If neither applies, members skip the Last1 ID veteran verification gate.


Org setup (admin)

  1. Confirm [Org] has a stable org slug (used for DD-214 review routing on Last1 ID).
  2. Enable veteran verification policy (explicit flag or VSO bundle).
  3. Enroll programs that require verified veterans.
  4. Assign org admins who can review DD-214 submissions on Org Settings → Verification.

Member journey (veteran)

Step 1: Invite

[Org] admin invites the veteran as a beneficiary. The invite email includes a four-step checklist:

  1. Accept invitation
  2. Sign in with Last1 ID
  3. Verify veteran status (DD-214 or VA confirmation)
  4. Return to last1.app for program progress

Step 2: Accept + Last1 ID

  1. Veteran opens the invite link on last1.app.
  2. Veteran accepts the invitation and creates or links a Last1 ID account.
  3. After accept, veteran lands on Member setup (/member/setup) with a stepper showing remaining steps.

Step 3: Verify on Last1 ID

  1. Veteran clicks Verify veteran status on last1.app.
  2. last1.app redirects through /api/last1/credentials-redirect to auth.last1.id/credentials with:
  3. context=org_invite
  4. org=<org-slug> (routing)
  5. org_name=<canonical org name> (display on the verification card)
  6. return=<last1.app return URL>
  7. On Last1 ID, the veteran sees a banner titled Veteran verification for [Org] using [Org]'s canonical name, not a guessed slug label.
  8. Veteran uploads DD-214 (recommended) or completes VA confirmation in the Last1 ID sequence.

Step 4: Return to program progress

  1. After submission, veteran returns to last1.app (button on Last1 ID or member dashboard).
  2. Gate A (submitted): Program progress unlocks once verification is submitted (pending_review, confirmed, or verification method set).
  3. Gate B (approved): Full outcome loop close still requires org approval of veteran status.

Org admin responsibilities

Phase Org action Veteran sees
Invite sent Send beneficiary invite Email + accept page checklist with [Org] name
Pending review Open Verification tab; review DD-214 Pending state on Last1 ID + member stepper
Approved Confirm veteran verification Verified badge; loop close enabled (Gate B)
Denied (re-submittable) Deny with clear reason Veteran can re-submit on Last1 ID

Pathway 1 (org review): DD-214 review and approval happen in [Org] admin UI. Platform admin review is not required for org-invited veterans when org routing is configured.


Gates reference

Gate Unlocks Requirement
Gate A /member/progress output actions Veteran submitted verification on Last1 ID
Gate B Full loop attestation / veteran_verified close [Org] approved DD-214 / veteran status

Progress blocking surfaces show guidance (stepper + CTAs), not a dead wall.


LastVet iOS: enrollment must match login identity

When a veteran uses LastVet iOS (Sign in with Last1 ID), program visibility follows this chain (verified in prod):

Org enrolls beneficiary on last1.app
  → program_beneficiaries (beneficiary_id × program_id)
  → beneficiaries.user_id
  → user_profiles.last1_identity_id

Veteran opens LastVet iOS (Sign in with Last1 ID)
  → id_token.sub → last.vet-api veterans.last1_identity_id
  → BFF GET …/coordination/summary/by-last1id/{identityId}
  → same enrollments as last1.app for that identity

Programs appear immediately when the enrollment's last1_identity_id matches the Last1 ID the veteran signed into LastVet with. If they differ, the app correctly shows that identity's programs only (not another account's cohort). Real veterans have one Last1 ID, so this is normally automatic. Operator testing with multiple test Last1 IDs can look like a broken pipeline when it is actually identity parity drift.

WIN / bulk onboarding checklist (per veteran)

Before marking a veteran "live" on LastVet iOS:

  • [ ] Veteran accepted invite and linked Last1 ID on last1.app (user_profiles.last1_identity_id set).
  • [ ] Org enrolled that beneficiary (same email / same last1.app user as the invite).
  • [ ] Enrollment identity = login identity: the enrolled beneficiary's last1_identity_id equals the Last1 ID the veteran uses to sign into LastVet iOS (Profile → masked Last1 ID prefix/suffix spot-check for pilot vets).
  • [ ] Veteran sees enrolled program(s) on last1.app /member/progress and LastVet Home → YOUR TURN (or Pipeline once home IA ships).

If web shows a program but iOS does not, check identity parity first (two test accounts is the common operator failure mode), then home IA (archived/completed programs not yet surfaced outside the carousel).


Technical contract (for implementers)

Canonical org name must survive the last1.app → Last1 ID hop:

last1.app button
  → /api/last1/credentials-redirect?org=<slug>&org_name=<canonical>
  → auth.last1.id/credentials?...&org_name=<canonical>
  → OrgInviteVeteranWizard displays org_name (fallback: slug title-case, then "your organization")

Proof of agnosticism: Use an org whose canonical name differs from slug title-case (e.g. slug vetclaims-ai, name VetClaims.ai). The Last1 ID card must show VetClaims.ai, not Vetclaims Ai.


Smoke test checklist (any org)

  • [ ] Org has veteran verification policy enabled
  • [ ] Invite email shows [Org] name and four-step checklist
  • [ ] Accept → setup stepper shows [Org] name
  • [ ] Verify link includes org_name= with canonical name
  • [ ] Last1 ID card title reads Veteran verification for [Org] (canonical)
  • [ ] DD-214 submit → Gate A unlocks progress on last1.app
  • [ ] Org approve on Verification tab → Gate B / verified state
  • [ ] LastVet iOS: enrollment last1_identity_id = veteran's Last1 ID login (see § LastVet iOS above)
  • [ ] LastVet iOS: enrolled program visible on Home after sign-in (YOUR TURN or program detail)

First production instance

Warriors In Need (WIN) is the first org to run this SOP end-to-end. See TRACK_A_TONY_WIN_ORG_RUNBOOK.md for WIN-specific IDs, Tony walkthrough, and VetClaims program context. WIN is an example, not a substitute for this SOP.