Skip to content

Feature: configurable password strength policy for local accounts #4184

Description

@nikmak88

Related to

Web-Frontend (what users interact with)

Impact

security improvements

Missing Feature

Summary

Semaphore does not enforce any strength requirements on local (non-external) account passwords. A password of a single character can be set through the API. There is no configuration option to require a minimum length or any character-class complexity.

Current behavior

The web UI performs a client-side minimum-length check, but it is not enforced on the server, so it is bypassed by calling the API directly.
POST /api/users, PUT /api/users/{id}/ and POST /api/users/{id}/password accept a password of any length, including one character.
No config.json / environment option exists to set a policy.
Steps to reproduce

As an admin, call POST /api/users with a one-character password.
The user is created (HTTP 201); the weak password is accepted.
(Any Semaphore instance with a local admin account reproduces this; no special setup.)

Expected behavior

A configurable, server-side password policy applied to every path that sets a local password (API and CLI), so it cannot be bypassed by talking to the API directly. External (LDAP/OIDC) accounts, which carry no local password, are unaffected.

Proposed solution

Add an optional password_policy config block (and matching SEMAPHORE_PASSWORD_* environment variables):

"password_policy": {
"min_length": 12,
"require_uppercase": true,
"require_lowercase": true,
"require_number": true,
"require_symbol": true
}
Enforced centrally in the DB store layer (db/sql/user.go: CreateUser, UpdateUser, SetUserPassword) via a shared db.ValidatePassword, so the API and the CLI share one check. Validation failures return the existing validation-error type, surfaced by the API as HTTP 400 with a descriptive message.

Implementation

I have a working patch tested with local users, which I can share on a new PR if needed.

Design

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions