Outcome
Set a new password for the exact management-authorized target without activating them; verify revocation separately.
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.admin_reset --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
| Field | Required | Meaning |
|---|---|---|
userId | Yes | Existing 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. |
newPassword | Yes | Privately 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
-
Changes only the management-authorized target password without a current-password challenge; does not activate that account.
-
Resets lockout after writing the password, then attempts refresh/session revocation. Storage is non-atomic; audit is nonfatal and no lifecycle notification is emitted by this handler.
Interpret the response
Sets the selected managed-user password without their current password. Target-user/organization authority remains required, and authenticated denial can return 401. Same stored password is refused for active users.
The active-only password lookup may return no row for an inactive target accepted by admin discovery; reset still changes that target password without activating the account. PasswordConfigured does not prove successful sign-in.
Password write and lockout reset precede non-atomic refresh/session revocation. A reset failure can return 500 after the password changes; swallowed session-store failures can still yield success. The handler does not increment token_version or clear target cookies. Audit is nonfatal and this handler emits no lifecycle event.
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.
Organization administrator resets exactly the selected managed-user password
Input · payload.json:
{
"userId": "usr_managed",
"newPassword": "FixtureChanged94!Example"
}
CLI:
topolo actions validate app_topolo_auth.user_password.admin_reset --data @payload.json --json
topolo actions plan app_topolo_auth.user_password.admin_reset --data @payload.json --confirm --json
topolo actions call app_topolo_auth.user_password.admin_reset --data @payload.json --confirm --json
MCP call after validation and plan review:
{
"tool": "topolo_call_action",
"arguments": {
"actionId": "app_topolo_auth.user_password.admin_reset",
"input": {
"userId": "usr_managed",
"newPassword": "FixtureChanged94!Example"
},
"confirm": true
}
}
Captured local handler response · HTTP 200:
{
"success": true,
"message": "Password updated successfully",
"data": {
"userId": "usr_managed",
"passwordUpdated": true
},
"timestamp": "2026-10-02T00:00:00.000Z"
}
Managed inactive-user password reset does not activate that user
Input · payload.json:
{
"userId": "usr_inactive",
"newPassword": "FixtureChanged94!Example"
}
CLI:
topolo actions validate app_topolo_auth.user_password.admin_reset --data @payload.json --json
topolo actions plan app_topolo_auth.user_password.admin_reset --data @payload.json --confirm --json
topolo actions call app_topolo_auth.user_password.admin_reset --data @payload.json --confirm --json
MCP call after validation and plan review:
{
"tool": "topolo_call_action",
"arguments": {
"actionId": "app_topolo_auth.user_password.admin_reset",
"input": {
"userId": "usr_inactive",
"newPassword": "FixtureChanged94!Example"
},
"confirm": true
}
}
Captured local handler response · HTTP 200:
{
"success": true,
"message": "Password updated successfully",
"data": {
"userId": "usr_inactive",
"passwordUpdated": true
},
"timestamp": "2026-10-02T00:00:00.000Z"
}
Verify the result
-
Require acknowledgment userId to match the exact selected target. Read users.get passwordConfigured/status and user_security.get lockout state independently.
-
Use the intended user-approved sign-in flow to verify the replacement password; read exact-user sessions and test old-session/access-token rejection separately. Successful password storage does not prove activation, revocation or secret delivery to the user.
Errors and recovery
Anonymous managed-user password reset is refused
Captured local refusal · HTTP 401:
{
"input": {
"userId": "usr_managed",
"newPassword": "FixtureChanged94!Example"
},
"response": {
"success": false,
"error": {
"message": "Access token required",
"code": "AUTH_ERROR",
"details": null,
"timestamp": "2026-10-02T00:00:00.000Z"
}
}
}
Ordinary member cannot reset a managed user
Captured local refusal · HTTP 401:
{
"input": {
"userId": "usr_managed",
"newPassword": "FixtureChanged94!Example"
},
"response": {
"success": false,
"error": {
"message": "Access denied: You can only reset passwords for users in your organization",
"code": "AUTH_ERROR",
"details": null,
"timestamp": "2026-10-02T00:00:00.000Z"
}
}
}
Known foreign-organization user cannot be reset
Captured local refusal · HTTP 401:
{
"input": {
"userId": "usr_foreign",
"newPassword": "FixtureChanged94!Example"
},
"response": {
"success": false,
"error": {
"message": "Access denied: You can only reset passwords for users in your organization",
"code": "AUTH_ERROR",
"details": null,
"timestamp": "2026-10-02T00:00:00.000Z"
}
}
}
Missing managed user is not provisioned
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"
}
}
}
Admin reset also refuses the existing password
Captured local refusal · HTTP 400:
{
"input": {
"userId": "usr_managed",
"newPassword": "FixtureCurrent83!Example"
},
"response": {
"success": false,
"error": {
"message": "New password must be different from the current password",
"code": "VALIDATION_ERROR",
"details": {
"newPassword": true
},
"timestamp": "2026-10-02T00:00:00.000Z"
}
}
}
Security reset fails after the password write and before session revocation
Captured local refusal · HTTP 500:
{
"input": {
"userId": "usr_managed",
"newPassword": "FixtureLater62!Example"
},
"response": {
"success": false,
"error": {
"message": "Isolated security reset failure",
"code": "SERVER_ERROR",
"details": null,
"timestamp": "2026-10-02T00:00:00.000Z"
}
}
}
Blind retry after a partial failure is refused because the password already changed
Captured local refusal · HTTP 400:
{
"input": {
"userId": "usr_managed",
"newPassword": "FixtureLater62!Example"
},
"response": {
"success": false,
"error": {
"message": "New password must be different from the current password",
"code": "VALIDATION_ERROR",
"details": {
"newPassword": true
},
"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.