Users and roles
SimpleDeploy ships with three roles. Pick the lowest privilege that gets the job done.
| Role | Granted apps (read) | Granted apps (mutate) | Create / delete apps | All apps | User mgmt | System / registries / docker / git sync |
|---|---|---|---|---|---|---|
viewer | yes | no | no | no | no | no |
manage | yes | yes (start/stop/restart, scale, pull, edit compose+env, redeploy, rollback, backup config + run + restore, per-app alerts/webhooks) | no | no | no | no |
super_admin | yes | yes | yes | yes | yes | yes |
super_admin is the only role that can create or delete apps, manage users, or touch platform settings (system, registries, docker, git sync, DB backups). Bootstrap your first super_admin during setup.
manage users can do everything a super_admin can do inside an app they’ve been granted, except creation/deletion of the app itself. They cannot see the Users, Registries, Docker, System, or Git Sync pages.
viewer users can read everything for granted apps (overview, logs, metrics, events, versions, backup history) but cannot mutate anything.
Platform views are super_admin-only
Section titled “Platform views are super_admin-only”Reads of host- or platform-level state are gated to super_admin to keep host details and other tenants’ data invisible to scoped roles. Specifically, only super_admin may call:
GET /api/docker/info,/api/docker/disk-usage,/api/docker/images,/api/docker/networks,/api/docker/volumesGET /api/system/info,/api/system/storage-breakdown,/api/system/audit-configPOST /api/backups/test-s3
Cross-app read endpoints (GET /api/backups/summary, GET /api/apps/archived) are filtered server-side to the apps the caller has been granted; non-super_admin callers only see their own apps.
Create a user
Section titled “Create a user”- Settings, Users, Add user.
- Pick username, password, role (
manageorviewer). - Save.
- Open the new user, click Grant access, pick apps from the list.
# Interactive prompt for password (recommended)sudo simpledeploy users create --username alice --role manage
# Or via env var (for CI/scripts)SD_PASSWORD=hunter2 sudo simpledeploy users create --username alice --role manageThe CLI creates the user but does not grant per-app access. Use the UI or API to assign apps.
# Create the user (super_admin token required)curl -X POST https://manage.example.com/api/users \ -H "Authorization: Bearer $SD_API_KEY" \ -H "Content-Type: application/json" \ -d '{"username":"alice","password":"hunter2","role":"manage"}'
# Grant access to myappcurl -X POST https://manage.example.com/api/users/2/access \ -H "Authorization: Bearer $SD_API_KEY" \ -H "Content-Type: application/json" \ -d '{"app_slug":"myapp"}'Per-app access
Section titled “Per-app access”Non-super_admin users see only apps they’ve been granted. The dashboard list (/api/apps and the UI overview) is automatically filtered for manage and viewer callers. Apps they can’t see return 404 (not 403) so they don’t even know they exist.
Granting per-app access
Section titled “Granting per-app access”- Settings, Users.
- Click Edit on the user.
- Under App access, check the apps the user should have access to. Each toggle saves immediately.
- To revoke, uncheck the box.
Super admins automatically have access to every app, so the checkbox list is hidden when the user’s role is super_admin.
# List a user's grants (super_admin only)curl https://manage.example.com/api/users/2/access \ -H "Authorization: Bearer $SD_API_KEY"
# Grantcurl -X POST https://manage.example.com/api/users/2/access \ -H "Authorization: Bearer $SD_API_KEY" \ -H "Content-Type: application/json" \ -d '{"app_slug":"myapp"}'
# Revokecurl -X DELETE https://manage.example.com/api/users/2/access/myapp \ -H "Authorization: Bearer $SD_API_KEY"Inviting teammates
Section titled “Inviting teammates”There is no email invite flow. Workflow:
- Create the user with a temporary password.
- Send them the URL plus username + temp password over a private channel.
- They log in and change the password from the Profile page.
Removing access
Section titled “Removing access”# Delete the user entirelycurl -X DELETE https://manage.example.com/api/users/2 \ -H "Authorization: Bearer $SD_API_KEY"This also revokes all their API keys.
Session invalidation
Section titled “Session invalidation”JWT cookies carry a tv (token version) claim that is bumped server-side on:
- Logout — the cookie is invalidated immediately, not just cleared.
- Password change — every other session for that user is signed out.
- Role change — promotions and demotions take effect right away, not 24 hours later when the cookie expires.
If a session is suspected compromised, force-rotating the user’s password or role kills the existing JWT cookie even if the attacker holds it.