Topolo Docs Topolo Platform
Open workspace

Set my initial password

Establish the active authenticated subject first password while preserving onboarding sessions; refuse a stored password.

Outcome

Establish the active authenticated subject first password while preserving onboarding sessions; refuse a stored password.

These examples prove local handler behavior with real isolated hashing/SQL and explicitly simulated identity dependencies.

Before you start

  • Verify pinned identity and the published action. Change and initial setup require the access-token subject to equal userId; admin reset requires exact-target management authority. An authenticated denial is not proof of expired OAuth.

  • Supply actual passwords only through the intended private approved workflow. Published passwords belong solely to isolated synthetic fixtures. Do not log or share a live password/hash, use a public example password, or retain passwords as rollback material. Any temporary live payload requires restricted local handling and removal after execution.

  • Review the validated plan and effects before approval. Stored password configuration, usable sign-in, activation, session revocation and notification delivery are separate outcomes. Initial setup preserves sessions; change/reset revocation can fail after storage.

Discover the target

topolo whoami --json
topolo apps --json
topolo actions get app_topolo_auth.user_password.set_initial --detail --json

Use the exact authenticated subject for self actions or an authorized discovered managed user for admin reset. Read users.get passwordConfigured/status, user_security.get lockout and sessions.list for that exact user. Never retrieve a password hash as a discovery step.

Input fields

FieldRequiredMeaning
userIdYesExisting Auth identity from authorized discovery. Change and initial setup require the access-token sub to equal this user id; an administrator or userId-only alias does not substitute for self. Admin reset requires management authority over the selected target organization.
newPasswordYesPrivately supplied new password: 8–128 characters with lowercase, uppercase, a digit and one allowed punctuation character. It must differ from any stored password for change/reset. Initial setup requires an account without a password. Fixture values are synthetic and authorize no live mutation.

Effects

  • Sets the active authenticated subject first password; refuses any existing stored password.

  • Resets failed-login lockout after the password write and preserves onboarding sessions/refresh tokens. Audit failure is nonfatal.

Interpret the response

Sets a first password only when the active self identity has no stored password. PASSWORD_ALREADY_SET 409 refuses overwriting or repeated setup. It returns affected user identity and no secret/hash.

Initial setup intentionally retains onboarding sessions and refresh tokens. Password write precedes security reset; a later failure can leave a password stored, so a retry may return 409.

Successful storage is separate from usable password sign-in and account activation. Audit is nonfatal; do not treat acknowledgment as notification delivery or clear existing password/session state as compensation.

Worked examples

These are complete raw target-handler responses, not CLI/gateway envelopes or live authorization proof. All identifiers and passwords are synthetic and exist only in isolated fixtures. Replace targets through authorized discovery and supply real passwords privately. The CLI examples describe validation, plan review and the approved call using a payload; do not retain or share live plaintext payloads. --confirm assumes the intended mutation is authorized. Cookies and Bearer identity must consistently select the intended principal. Cookie-authenticated self change/setup also require the approved CSRF transport. Password storage, actual sign-in and old-session rejection require separate verification.

Passwordless self establishes a first password while retaining onboarding sessions

Input · payload.json:

{
  "userId": "usr_initial",
  "newPassword": "FixtureChanged94!Example"
}

CLI:

topolo actions validate app_topolo_auth.user_password.set_initial --data @payload.json --json
topolo actions plan app_topolo_auth.user_password.set_initial --data @payload.json --confirm --json
topolo actions call app_topolo_auth.user_password.set_initial --data @payload.json --confirm --json

MCP call after validation and plan review:

{
  "tool": "topolo_call_action",
  "arguments": {
    "actionId": "app_topolo_auth.user_password.set_initial",
    "input": {
      "userId": "usr_initial",
      "newPassword": "FixtureChanged94!Example"
    },
    "confirm": true
  }
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "Password set successfully",
  "data": {
    "userId": "usr_initial",
    "passwordUpdated": true
  },
  "timestamp": "2026-10-02T00:00:00.000Z"
}

A separate passwordless identity establishes its own first password

Input · payload.json:

{
  "userId": "usr_initial_other",
  "newPassword": "FixtureLater62!Example"
}

CLI:

topolo actions validate app_topolo_auth.user_password.set_initial --data @payload.json --json
topolo actions plan app_topolo_auth.user_password.set_initial --data @payload.json --confirm --json
topolo actions call app_topolo_auth.user_password.set_initial --data @payload.json --confirm --json

MCP call after validation and plan review:

{
  "tool": "topolo_call_action",
  "arguments": {
    "actionId": "app_topolo_auth.user_password.set_initial",
    "input": {
      "userId": "usr_initial_other",
      "newPassword": "FixtureLater62!Example"
    },
    "confirm": true
  }
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "Password set successfully",
  "data": {
    "userId": "usr_initial_other",
    "passwordUpdated": true
  },
  "timestamp": "2026-10-02T00:00:00.000Z"
}

Verify the result

  • Require acknowledgment userId to equal the subject and read users.get passwordConfigured without retrieving a hash.

  • Privately verify the new password through the normal sign-in flow. Confirm intended onboarding session continuity; initial setup does not revoke existing sessions. After 500, stored configuration may already be true and a repeated setup may conflict.

Errors and recovery

Initial setup requires authenticated self identity

Captured local refusal · HTTP 401:

{
  "input": {
    "userId": "usr_initial",
    "newPassword": "FixtureChanged94!Example"
  },
  "response": {
    "success": false,
    "error": {
      "message": "Access token required",
      "code": "AUTH_ERROR",
      "details": null,
      "timestamp": "2026-10-02T00:00:00.000Z"
    }
  }
}

Administrator cannot use the self initial-password action for another user

Captured local refusal · HTTP 403:

{
  "input": {
    "userId": "usr_initial",
    "newPassword": "FixtureChanged94!Example"
  },
  "response": {
    "success": false,
    "error": {
      "message": "You can only set your own password",
      "code": "FORBIDDEN",
      "details": null,
      "timestamp": "2026-10-02T00:00:00.000Z"
    }
  }
}

Missing initial-password identity is not created

Captured local refusal · HTTP 404:

{
  "input": {
    "userId": "usr_missing",
    "newPassword": "FixtureChanged94!Example"
  },
  "response": {
    "success": false,
    "error": {
      "message": "User not found",
      "code": "NOT_FOUND",
      "details": null,
      "timestamp": "2026-10-02T00:00:00.000Z"
    }
  }
}

Initial setup cannot overwrite a stored password even when repeated

Captured local refusal · HTTP 409:

{
  "input": {
    "userId": "usr_initial",
    "newPassword": "FixtureChanged94!Example"
  },
  "response": {
    "success": false,
    "error": {
      "message": "A password is already set for this account. Use change password instead.",
      "code": "PASSWORD_ALREADY_SET",
      "details": null,
      "timestamp": "2026-10-02T00:00:00.000Z"
    }
  }
}

Initial setup can fail after the first password was stored

Captured local refusal · HTTP 500:

{
  "input": {
    "userId": "usr_initial_partial",
    "newPassword": "FixtureChanged94!Example"
  },
  "response": {
    "success": false,
    "error": {
      "message": "Isolated initial security reset failure",
      "code": "SERVER_ERROR",
      "details": null,
      "timestamp": "2026-10-02T00:00:00.000Z"
    }
  }
}

Retrying partial initial setup is a stored-password conflict

Captured local refusal · HTTP 409:

{
  "input": {
    "userId": "usr_initial_partial",
    "newPassword": "FixtureChanged94!Example"
  },
  "response": {
    "success": false,
    "error": {
      "message": "A password is already set for this account. Use change password instead.",
      "code": "PASSWORD_ALREADY_SET",
      "details": null,
      "timestamp": "2026-10-02T00:00:00.000Z"
    }
  }
}

Published recovery guidance

  • state_conflict (HTTP 409): Read the current resource state, reconcile the intended change, and retry only if still valid.

  • AUTH_ERROR (HTTP 401): Verify the pinned identity first. For an authenticated admin-reset denial, retain the refusal and obtain the intended target authority; do not widen context or assume OAuth expiry.

  • FORBIDDEN (HTTP 403): Use the intended self principal and approved browser session/CSRF transport. Administrator authority cannot substitute for self; never bypass CSRF.

  • NOT_FOUND (HTTP 404): Refresh authorized discovery. Self password reads require an active user; do not create a replacement identity.

  • VALIDATION_ERROR (HTTP 400): Have the intended user privately correct the password or choose a different valid value. After an uncertain prior write, verify current sign-in and stored configuration before preparing any retry.

  • PASSWORD_ALREADY_SET (HTTP 409): Read stored password configuration and verify the submitted password through the normal sign-in flow. Use a separately reviewed self-change or authorized recovery/reset workflow if needed; never clear the stored hash to force initial setup.

  • SERVER_ERROR (HTTP 500): Preserve the request/result. Treat password and revocation as independently unknown; inspect authorized configuration/session reads and use the intended sign-in flow. Do not blindly retry or restore an old password. Authorized operator investigation may be needed.

Recovery boundaries

The prior password is not recoverable or automatically restored. Never store the prior hash/password as rollback material. After an unknown outcome inspect stored configuration and separately verify sign-in/revocation before reviewing any new password action. A further change/reset is a separately approved mutation with the actual current password or authorized target recovery, and cannot restore prior sessions.

Discovery and evidence

This record belongs to app_topolo_auth. Fixtures prove real controller authority, PBKDF2 hashing/verification, canonical password/security/session SQL and partial failure behavior with simulated tokens and organization hydration/admin lookup. Lifecycle notification is unconfigured; no live user, password, delivery, session or OAuth state was changed. Neither local capture nor stored configuration proves deployed authorization, usable sign-in, token invalidation or production completion.