Appearance
List all users (admin only)
GET
/users
Returns all user accounts sorted alphabetically. Includes login tracking fields (last_sign_in_at, failed_attempts, locked_at) for admin monitoring. Requires admin role — returns 403 for non-admin users.
Authorizations
cookieAuth
Type
API Key (cookie: _vulcan_session)
or
tokenAuth
Personal access token authentication. Send via Authorization header: Authorization: Token vulcan_xxx. Tokens are SHA-256 hashed server-side (never stored in plaintext). Scopes: read (GET), write (mutations), admin (everything). Create tokens via Settings → API Tokens in the web UI.
Type
HTTP (token)
Responses
All user accounts
application/json
JSON { "id": 1, "name": "Demo Admin", "email": "admin@example.com", "provider": null, "admin": true, "last_sign_in_at": "2026-05-28T15:00:00Z", "failed_attempts": 0, "locked_at": null }, { "id": 5, "name": "Bernice Deckow", "email": "bernice.deckow@example.com", "provider": null, "admin": false, "last_sign_in_at": null, "failed_attempts": 0, "locked_at": null }
[
]
Update the signed-in user's own profile
PUT
/users
Updates the current user's profile (Devise registration update). Field-sensitivity policy: name and slack_user_id save without a password; changing the email — the login identifier — requires current_password (re-authentication for sensitive changes). When email confirmation is enabled, an email change is held in unconfirmed_email until the confirmation link is followed; otherwise it applies immediately. Provider-managed users (OIDC/LDAP) cannot change email here — the identity provider owns it and the parameter is ignored.
Authorizations
cookieAuth
Type
API Key (cookie: _vulcan_session)
or
tokenAuth
Personal access token authentication. Send via Authorization header: Authorization: Token vulcan_xxx. Tokens are SHA-256 hashed server-side (never stored in plaintext). Scopes: read (GET), write (mutations), admin (everything). Create tokens via Settings → API Tokens in the web UI.
Type
HTTP (token)
Request Body
application/json
JSON "user": { "name": "Jane Doe", "slack_user_id": "U123456" }
{
}
Responses
Profile updated
application/json
JSON "toast": { "title": "Account updated.", "message": [ "Profile updated successfully." ], "variant": "success" }
{
}
Full replacement of user attributes (admin only)
PUT
/users/{userId}
Full replacement — all fields required. Updates a user's name, email, or admin status. Requires admin role. Prevents the last admin from demoting themselves. Sends a Slack notification when admin status changes (if Slack is configured). Returns both a toast and the updated user object.
Authorizations
cookieAuth
Type
API Key (cookie: _vulcan_session)
or
tokenAuth
Personal access token authentication. Send via Authorization header: Authorization: Token vulcan_xxx. Tokens are SHA-256 hashed server-side (never stored in plaintext). Scopes: read (GET), write (mutations), admin (everything). Create tokens via Settings → API Tokens in the web UI.
Type
HTTP (token)
Request Body
application/json
JSON "user": { "admin": true }
{
}
Responses
User updated
application/json
JSON "toast": { "title": "User updated.", "message": [ "Successfully updated user." ], "variant": "success" }, "user": { "id": 42, "name": "Jane Doe", "email": "jane.doe@example.org", "admin": true }
{
}
Delete a user (admin only)
DELETE
/users/{userId}
Permanently deletes a user account. Requires admin role. Cannot delete the last remaining site admin, nor a user who is the only admin of any project — transfer the admin role first. All project memberships and associated data are cleaned up via dependent destroy.
Authorizations
cookieAuth
Type
API Key (cookie: _vulcan_session)
or
tokenAuth
Personal access token authentication. Send via Authorization header: Authorization: Token vulcan_xxx. Tokens are SHA-256 hashed server-side (never stored in plaintext). Scopes: read (GET), write (mutations), admin (everything). Create tokens via Settings → API Tokens in the web UI.
Type
HTTP (token)
Responses
User removed
application/json
JSON "toast": { "title": "User removed.", "message": [ "Successfully removed user." ], "variant": "success" }
{
}
Partial update of user attributes (admin only)
PATCH
/users/{userId}
Partial update — send only changed fields. Updates a user's name, email, or admin status. Requires admin role. Prevents the last admin from demoting themselves. Sends a Slack notification when admin status changes (if Slack is configured). Returns both a toast and the updated user object.
Authorizations
cookieAuth
Type
API Key (cookie: _vulcan_session)
or
tokenAuth
Personal access token authentication. Send via Authorization header: Authorization: Token vulcan_xxx. Tokens are SHA-256 hashed server-side (never stored in plaintext). Scopes: read (GET), write (mutations), admin (everything). Create tokens via Settings → API Tokens in the web UI.
Type
HTTP (token)
Request Body
application/json
JSON "user": { "admin": true }
{
}
Responses
User updated
application/json
JSON "toast": { "title": "User updated.", "message": [ "Successfully updated user." ], "variant": "success" }, "user": { "id": 42, "name": "Jane Doe", "email": "jane.doe@example.org", "admin": true }
{
}
My Comments page — user's comments across accessible projects
GET
/users/{userId}/comments
Returns paginated comments authored by the specified user across all projects the requesting user can access. Scoped by project visibility, not identity — this is a filtered view, not a privacy boundary. Supports triage status filtering, project filtering, and pagination.
Authorizations
cookieAuth
Type
API Key (cookie: _vulcan_session)
or
tokenAuth
Personal access token authentication. Send via Authorization header: Authorization: Token vulcan_xxx. Tokens are SHA-256 hashed server-side (never stored in plaintext). Scopes: read (GET), write (mutations), admin (everything). Create tokens via Settings → API Tokens in the web UI.
Type
HTTP (token)
Parameters
Query Parameters
triage_status
Filter the user's comments by triage disposition. Absent or "all" returns comments in any status — this page has no default filter.
Type
string
Valid values
"all""pending""concur""concur_with_comment""non_concur""duplicate""informational""needs_clarification""withdrawn""addressed_by"Example
"concur"Default
"all"page
Page number for paginated results (1-based).
Type
integer
Example
1Minimum
1Default
1per_page
Number of items to return per page.
Type
integer
Example
25Minimum
1Maximum
1000Default
25project_id
Filter comments to a specific project.
Type
integer
Example
3Responses
Paginated user comments with project/component context
application/json
JSON "rows": [ { "id": 29, "project_id": 3, "project_name": "vSphere 7.0", "component_id": 4, "component_name": "Photon OS 3", "rule_id": 2397, "rule_displayed_name": "PHOS-03-000039", "commentable_type": "BaseRule", "section": "fixtext", "comment": "vSphere 7.0: fix command targets ESXi 6.7 path.", "created_at": "2026-05-19 14:08:18 UTC", "triage_status": "pending", "responses_count": 0, "reactions": { "up": 0, "down": 0, "mine": null } } ], "pagination": { "page": 1, "per_page": 25, "total": 12 }
{
}
Unlink an OAuth provider from the current user
POST
/users/unlink_identity
Removes an OAuth provider link (GitHub, LDAP, OIDC) from the current user's account. Requires the user's current password to confirm. The user must have local login credentials before unlinking to avoid being locked out. Available from the user profile page.
Authorizations
cookieAuth
Type
API Key (cookie: _vulcan_session)
or
tokenAuth
Personal access token authentication. Send via Authorization header: Authorization: Token vulcan_xxx. Tokens are SHA-256 hashed server-side (never stored in plaintext). Scopes: read (GET), write (mutations), admin (everything). Create tokens via Settings → API Tokens in the web UI.
Type
HTTP (token)
Request Body
application/json
JSON "current_password": "MyCurrentP@ssw0rd!", "provider": "github"
{
}
Responses
Provider unlinked
application/json
JSON "toast": { "title": "Provider unlinked.", "message": [ "GitHub identity removed from your account." ], "variant": "success" }
{
}
Create a new user (admin only)
POST
/users/admin_create
Creates a new user account. Requires admin role. Three modes based on password and SMTP config: (1) password provided — user can sign in immediately, (2) no password + SMTP enabled — sends setup email via Devise, (3) no password + no SMTP — returns a reset URL the admin delivers manually. Skips email confirmation.
Authorizations
cookieAuth
Type
API Key (cookie: _vulcan_session)
or
tokenAuth
Personal access token authentication. Send via Authorization header: Authorization: Token vulcan_xxx. Tokens are SHA-256 hashed server-side (never stored in plaintext). Scopes: read (GET), write (mutations), admin (everything). Create tokens via Settings → API Tokens in the web UI.
Type
HTTP (token)
Request Body
application/json
JSON "user": { "name": "Jane Doe", "email": "jane.doe@example.org", "admin": false, "password": "SecureP@ssw0rd2026!" }
{
}
Responses
User created (response varies by mode)
application/json
JSON "toast": { "title": "User created.", "message": [ "User jane.doe@example.org created with the provided password." ], "variant": "success" }, "user": { "id": 42, "name": "Jane Doe", "email": "jane.doe@example.org", "admin": false }
{
}
Send Devise password reset email (admin only)
POST
/users/{userId}/send_password_reset
Triggers a Devise password reset email to the specified user. Requires admin role and SMTP to be configured. Returns 422 if SMTP is disabled — use the generate_reset_link endpoint instead. Returns 500 if email delivery fails.
Authorizations
cookieAuth
Type
API Key (cookie: _vulcan_session)
or
tokenAuth
Personal access token authentication. Send via Authorization header: Authorization: Token vulcan_xxx. Tokens are SHA-256 hashed server-side (never stored in plaintext). Scopes: read (GET), write (mutations), admin (everything). Create tokens via Settings → API Tokens in the web UI.
Type
HTTP (token)
Responses
Reset email sent successfully
application/json
JSON "toast": { "title": "Reset email sent.", "message": [ "Password reset email sent to jane.doe@example.org." ], "variant": "success" }
{
}
Generate a password reset URL without sending email (admin only)
POST
/users/{userId}/generate_reset_link
Generates a Devise reset token and returns the full reset URL. Does not send email — the admin copies the link and delivers it to the user through a secure channel. Requires admin role. Works regardless of SMTP config.
Authorizations
cookieAuth
Type
API Key (cookie: _vulcan_session)
or
tokenAuth
Personal access token authentication. Send via Authorization header: Authorization: Token vulcan_xxx. Tokens are SHA-256 hashed server-side (never stored in plaintext). Scopes: read (GET), write (mutations), admin (everything). Create tokens via Settings → API Tokens in the web UI.
Type
HTTP (token)
Responses
Reset link generated
application/json
JSON "toast": { "title": "Reset link generated.", "message": [ "Reset link generated. Copy it and deliver to the user." ], "variant": "success" }, "reset_url": "https://vulcan.example.org/users/password/edit?reset_password_token=abc123def456"
{
}
Directly set a user's password (admin only)
POST
/users/{userId}/set_password
Sets the password for a user account without requiring the old password. Requires admin role. The password must meet the configured minimum length (default 15 characters). Does not send any email notification. Used for urgent password resets when SMTP is unavailable.
Authorizations
cookieAuth
Type
API Key (cookie: _vulcan_session)
or
tokenAuth
Personal access token authentication. Send via Authorization header: Authorization: Token vulcan_xxx. Tokens are SHA-256 hashed server-side (never stored in plaintext). Scopes: read (GET), write (mutations), admin (everything). Create tokens via Settings → API Tokens in the web UI.
Type
HTTP (token)
Request Body
application/json
JSON "user": { "password": "SecureP@ssw0rd2026!" }
{
}
Responses
Password updated
application/json
JSON "toast": { "title": "Password updated.", "message": [ "Password updated for jane.doe@example.org." ], "variant": "success" }
{
}
Lock a user account (admin only)
POST
/users/{userId}/lock
Prevents the user from signing in. Requires admin role. Returns 422 if the admin attempts to lock their own account. Creates an audit trail entry recording who locked the account and when.
Authorizations
cookieAuth
Type
API Key (cookie: _vulcan_session)
or
tokenAuth
Personal access token authentication. Send via Authorization header: Authorization: Token vulcan_xxx. Tokens are SHA-256 hashed server-side (never stored in plaintext). Scopes: read (GET), write (mutations), admin (everything). Create tokens via Settings → API Tokens in the web UI.
Type
HTTP (token)
Responses
Account locked successfully
application/json
JSON "toast": { "title": "Account locked.", "message": [ "Account jane.doe@example.org locked." ], "variant": "success" }, "user": { "id": 42, "name": "Jane Doe", "email": "jane.doe@example.org", "admin": false, "locked_at": "2026-05-28T15:00:00Z" }
{
}
Unlock a locked user account (admin only)
POST
/users/{userId}/unlock
Restores sign-in access for a locked user account. Requires admin role. Clears failed_attempts counter and locked_at timestamp. Creates an audit trail entry recording who unlocked the account.
Authorizations
cookieAuth
Type
API Key (cookie: _vulcan_session)
or
tokenAuth
Personal access token authentication. Send via Authorization header: Authorization: Token vulcan_xxx. Tokens are SHA-256 hashed server-side (never stored in plaintext). Scopes: read (GET), write (mutations), admin (everything). Create tokens via Settings → API Tokens in the web UI.
Type
HTTP (token)
Responses
Account unlocked
application/json
JSON "toast": { "title": "Account unlocked.", "message": [ "Account jane.doe@example.org unlocked." ], "variant": "success" }, "user": { "id": 42, "name": "Jane Doe", "email": "jane.doe@example.org", "admin": false, "locked_at": null }
{
}