Skip to content

User Management

Deployment Model

This page covers self-hosted Dagu. On self-hosted Dagu, creating, updating, and deleting users requires an active self-host license. Listing users, viewing user details, and password operations work with builtin auth. Hosted Dagu Cloud includes user management by default. See the pricing page for current self-host and cloud availability.

Requires auth.mode: builtin (default).

Initial Setup

On first launch with builtin auth and no existing users, an admin account must be created. There are four ways to do this:

Via the guided installer — the script installers can collect the first admin credentials for you and use the same bootstrap flow as initial_admin.

Via config or environment variables — set initial_admin in the config file or DAGU_AUTH_BUILTIN_INITIAL_ADMIN_USERNAME / DAGU_AUTH_BUILTIN_INITIAL_ADMIN_PASSWORD environment variables. The server creates the admin at startup. See Builtin Authentication for details.

Via the setup page — the web UI redirects to /setup automatically for manual installs that do not configure initial_admin.

Via API — call the setup endpoint directly:

bash
curl -X POST http://localhost:8080/api/v1/auth/setup \
  -H "Content-Type: application/json" \
  -d '{"username": "admin", "password": "your-password"}'

Response:

json
{
  "token": "eyJhbG...",
  "expiresAt": "2025-01-11T00:00:00Z",
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "username": "admin",
    "role": "admin",
    "createdAt": "2025-01-10T12:00:00Z",
    "updatedAt": "2025-01-10T12:00:00Z"
  }
}

The setup endpoint always creates an admin role user. It returns 403 if any user already exists.

Roles

RoleDAGs (read)DAGs (write)DAGs (run/stop)Audit LogsUser Management
adminyesyesyesyesyes
manageryesyesyesyesno
developeryesyesyesnono
operatoryesnoyesnono
vieweryesnononono

Source: internal/auth/role.go

User Object

Fields returned by the API:

FieldTypeDescription
idstringUUID, auto-generated
usernamestring1–64 characters, must be unique
rolestringadmin, manager, developer, operator, viewer
authProviderstringbuiltin or oidc
isDisabledbooleanDisabled accounts cannot log in
createdAtstringISO 8601 timestamp
updatedAtstringISO 8601 timestamp

API

All endpoints require admin role. On self-hosted Dagu, create, update, and delete operations return 403 when the required self-host license is not active.

List Users

GET /api/v1/users

bash
curl http://localhost:8080/api/v1/users \
  -H "Authorization: Bearer $TOKEN"
json
{
  "users": [
    {
      "id": "...",
      "username": "admin",
      "role": "admin",
      "authProvider": "builtin",
      "createdAt": "2025-01-01T00:00:00Z",
      "updatedAt": "2025-01-01T00:00:00Z"
    }
  ]
}

Create User

POST /api/v1/users

bash
curl -X POST http://localhost:8080/api/v1/users \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"username": "alice", "password": "min-8-chars", "role": "developer"}'

Returns 201 with {"user": User}. Returns 409 if username exists. Returns 400 for invalid role or weak password.

Get User

GET /api/v1/users/{userId}

bash
curl http://localhost:8080/api/v1/users/USER_ID \
  -H "Authorization: Bearer $TOKEN"

Returns 200 with {"user": User}. Returns 404 if not found.

Update User

PATCH /api/v1/users/{userId}

All fields are optional. You cannot disable your own account.

bash
curl -X PATCH http://localhost:8080/api/v1/users/USER_ID \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"role": "manager", "isDisabled": false}'

Returns 200 with updated user. Returns 409 if new username conflicts.

Delete User

DELETE /api/v1/users/{userId}

You cannot delete your own account.

bash
curl -X DELETE http://localhost:8080/api/v1/users/USER_ID \
  -H "Authorization: Bearer $TOKEN"

Returns 204 on success. Returns 403 if attempting self-deletion.

Reset Password

POST /api/v1/users/{userId}/reset-password

Admin resets another user's password. This works with builtin auth and does not require a self-host license.

bash
curl -X POST http://localhost:8080/api/v1/users/USER_ID/reset-password \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"newPassword": "new-password"}'

Change Own Password

POST /api/v1/auth/change-password

Any authenticated user can change their own password. Does not require admin role.

bash
curl -X POST http://localhost:8080/api/v1/auth/change-password \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"currentPassword": "old-password", "newPassword": "new-password"}'

Returns 401 if current password is wrong. Returns 400 if new password is too short.

Passwords

  • Minimum 8 characters
  • Hashed with bcrypt (cost factor 12)
  • Timing-attack safe: failed lookups compare against a dummy hash to prevent username enumeration

Storage

Users are stored as individual JSON files:

~/.local/share/dagu/users/
├── a1b2c3d4-....json
├── e5f6g7h8-....json
└── ...

Override with paths.users_dir in config or DAGU_USERS_DIR environment variable.

Released under the MIT License.