Users & ACL
Define users and fine-grained access control rules for multi-user deployments.
Defining Users
Users can be defined in config or created at runtime via the admin API.
Config Users
toml
[[users]]
username = "alice"
password_hash = "$argon2id$..." # argon2id hash
role = "admin" # admin, write, or read
[[users]]
username = "ci"
token = "ci-token-value"
role = "write"Runtime Users (Admin API)
bash
curl -X POST http://your-server:3000/admin/users \
-H "Authorization: Bearer admin-token" \
-H "Content-Type: application/json" \
-d '{"username": "bob", "role": "read"}'Runtime users are persisted in PostgreSQL and can be managed via the Admin API.
Roles
| Role | Permissions |
|---|---|
read | Read packages from any registry |
write | Read + publish/upload packages |
admin | Full access including user/ACL management |
ACL Rules
ACL rules grant additive permissions to specific users on specific registries:
toml
[[acl]]
user = "ci"
pattern = "npm/**"
permission = "write"
[[acl]]
user = "*"
pattern = "pypi/**"
permission = "read"Rules use glob patterns matched against {registry}/{package}. The most permissive matching rule wins.
How Permissions Resolve
- User's baseline role is checked
- All matching ACL rules are evaluated
- The most permissive result wins (additive model)
User Sources
Users from config and the database are merged by build_auth_and_acl():
- Config users are immutable — they cannot be modified via the admin API
- Runtime users are mutable and stored in PostgreSQL
Multi-Instance Coordination
When any instance modifies users or ACL via the admin API, it sends a PostgreSQL NOTIFY on the mise_server_auth channel. All other instances receive it and rebuild their auth/ACL stores.