Skip to main content

Profile and password changes

Two pairs of mutations let persons (and administrators) update profile and credentials:

Self-serviceAdmin
changeMyProfile(email, name)changeProfile(personId, email, name)
changeMyPassword(currentPassword, newPassword)changePassword(personId, password)

The self-service variants require the caller to be authenticated as the person being changed; the admin variants take a personId and are gated by per-target permission checks.

Self-service

Change my profile

mutation {
changeMyProfile(email: "[email protected]", name: "Alice Example") {
ok
error { code developerMessage }
}
}

Pass either field individually — omitted fields are left unchanged. Setting name: "" clears the name.

Errors:

CodeCause
NOT_A_PERSONCaller is authenticated via a permanent API key, not a person.
INVALID_EMAIL_FORMATEmail failed format validation.
EMAIL_ALREADY_EXISTSEmail is already used by another person.

A successful email change records email_change in the audit log.

Change my password

mutation {
changeMyPassword(currentPassword: "…", newPassword: "…") {
ok
error {
code
weakPasswordReasons
developerMessage
}
}
}

The caller must supply their current password — this protects against session hijack where an attacker holding a session token tries to lock out the user.

Errors:

CodeCause
NOT_A_PERSONCaller is authenticated via a permanent API key.
NO_PASSWORD_SETThe person has no password (IDP-only / passwordless-only). Use password reset to set the first password.
INVALID_PASSWORDcurrentPassword is wrong.
TOO_WEAKnewPassword failed password policy. weakPasswordReasons[] carries reasons including COMPROMISED (since 2.2).

A successful change records password_change in the audit log.

Admin

Change someone's profile

mutation {
changeProfile(personId: "…", email: "[email protected]", name: "Alice") {
ok
error { code developerMessage }
}
}

Gated by PERSON_CHANGE_PROFILE against the target's roles — a PROJECT_ADMIN can change profiles of persons whose roles do not exceed their own; SUPER_ADMIN is unrestricted.

Errors: PERSON_NOT_FOUND, INVALID_EMAIL_FORMAT, EMAIL_ALREADY_EXISTS.

Set someone's password

mutation {
changePassword(personId: "…", password: "…") {
ok
error {
code
weakPasswordReasons
developerMessage
}
}
}

Gated by PERSON_CHANGE_PASSWORD against the target's roles. No current-password check — the admin is trusted by policy.

Use cases:

  • Forced credential rotation after a known compromise.
  • Setting a temporary password before invoking forceSignOutPerson to lock the person out of their existing sessions.
  • Bulk migration scripts.

The new password is validated against the active password policy just like the self-service path. Records password_change in the audit log.

When the person has no password

changeMyPassword returns NO_PASSWORD_SET for persons created via IDP or passwordless-only flows. To set an initial password, either:

  • Trigger the public password reset flow.
  • Have an admin call changePassword directly.