Users and Roles
The Ioto authentication system uses a role-based authorization model where users are assigned roles that define their access capabilities. This page describes how to configure roles and manage users.
Access Roles
Access roles define user authorization levels and their specific abilities. Ioto uses a two-level authorization system where roles map to arrays of abilities.
Authentication roles for the Ioto web server are defined in the web.json5 configuration file via the auth.roles property.
Configuring Roles
Roles are configured as an object where each role name maps to an array of abilities:
{
auth: {
// Two-level roles structure: role name -> abilities
roles: {
public: [],
user: ['view', 'read'],
admin: ['user', 'edit', 'delete'],
owner: ['admin', 'billing', 'manage'],
},
login: '/api/public/login',
logout: '/api/public/logout',
}
}Role Definition Structure:
- Level 1: Role names (the object keys) - e.g.,
public,user,admin,owner - Level 2: Abilities (array values) - specific capabilities or included roles
Ability Types:
- Specific abilities: Strings like
'view','read','edit','delete','manage' - Included roles: References to other roles (e.g.,
'user','admin')
In the example above:
- public - No specific abilities, typically for unauthenticated access
- user - Has
viewandreadabilities - admin - Includes all
userabilities pluseditanddelete - owner - Includes all
adminabilities plusbillingandmanage
When a role includes another role (e.g., admin: ['user', ...]), it inherits all abilities from that role.
Role-Based Route Protection
The Ioto web server controls access to resources by assigning a specific "role" on a route that provides access to a document or resource. If the authenticated user has the required role or better, then the user is granted access.
Example route configuration:
web: {
routes: [
{match: '/api/admin/', role: 'admin'},
{match: '/api/user/', role: 'user'},
{match: '/api/'},
{match: '/admin/', role: 'admin'},
{match: '/user/', role: 'user'},
{},
],
}Each route specifies a matching URL prefix except for the last route which is a catchall. To restrict access, the route provides a "role" property that specifies the required user role to permit access.
In this example:
- Routes matching
/api/admin/and/admin/require the "admin" role - Routes matching
/api/user/and/user/require at least the "user" role (which "admin" users also have) - Routes matching
/api/(but not/api/admin/or/api/user/) are public - The catchall route
{}matches all other URLs and requires no authentication
Route Evaluation Order
Routes are evaluated in order from top to bottom. The first matching route determines the access requirements. More specific routes should be listed before more general routes.
For example, /api/admin/ must be listed before /api/ to ensure admin routes are properly protected.
Users and Passwords
Users are stored in the Ioto database together with their hashed and salted passwords and assigned access role.
User Database Schema
Each user entry typically contains:
- username - Unique user identifier
- password - Hashed and salted password
- role - Assigned access role (e.g., "user", "admin")
Password Security
Ioto uses strong password hashing with salts to protect user credentials:
- Passwords are never stored in plain text
- Each password is hashed with a unique salt
- The cryptMakePassword API uses industry-standard algorithms
Creating Users
User entries can be created in several ways:
1. Device Management Apps
In production, users are typically created by device management or admin applications using the cryptMakePassword API.
Example:
#include "ioto.h"
cchar *hashedPassword = cryptMakePassword("username", "plain-password", 0);
// Store hashedPassword in database with user record2. Development: Using the password Command
During development, you can generate hashed passwords using the password command-line utility.
Generate a hashed password:
password --password demo-pass ralphThis will generate a hashed password for user "ralph" with password "demo-pass" using SHA-256 (the default algorithm).
You can specify different algorithms:
# Using bcrypt (most secure for session-based auth)
password --algorithm bcrypt --password demo-pass alice
# Using MD5 (legacy, for compatibility only)
password --algorithm md5 --password demo-pass bob
# Using SHA-512
password --algorithm sha512 --password demo-pass charlieThe command will output the password hash in a format ready to add to your web.json5 users section.
3. Development: Configure Users in web.json5
For development and testing, you can define users directly in the web.json5 configuration file:
{
web: {
auth: {
roles: {
public: [],
user: ['view', 'read'],
admin: ['user', 'edit', 'delete'],
},
// Test users (for development only - NEVER use in production)
users: {
alice: {
password: 'SHA256:11c66702489123a02c7dd0860e47fc4989bb0805ba5835fbbb36f316ec83eb83',
role: 'admin'
},
bob: {
password: 'BF1:00128:ErbpOzVtv19JV20U:+i8PT5V/4GiR9Ti6NhoEkVG99dG78GuP',
role: 'user'
}
},
login: '/api/public/login',
logout: '/api/public/logout',
}
}
}To generate password hashes for your users:
# Generate a password hash for a user
password --password secret123 alice
# Copy the generated hash into web.json5 users sectionSECURITY WARNING: The users section in web.json5 is for development and testing only. In production, users should be managed through your application's user management interface and stored in the database.
User Role Hierarchy
Roles can be hierarchical by including other roles in their ability arrays. A role that includes another role inherits all of that role's abilities.
Example hierarchy:
roles: {
guest: ['view'],
user: ['guest', 'read', 'comment'],
support: ['user', 'help-users', 'view-logs'],
admin: ['support', 'edit', 'delete', 'configure'],
}In this configuration:
- guest - Can only
viewcontent - user - Inherits
viewfromguest, plusreadandcommentabilities - support - Inherits all
userabilities (view,read,comment), plushelp-usersandview-logs - admin - Inherits all
supportabilities, plusedit,delete, andconfigure
A user with the "admin" role can:
- Access any resource requiring "support", "user", or "guest" roles
- Perform any action requiring abilities:
view,read,comment,help-users,view-logs,edit,delete,configure
Checking Abilities
When the web server checks if a user can access a route with role: 'user':
- If the user's role is exactly 'user', access is granted
- If the user's role includes 'user' in its abilities array (e.g., 'admin' includes 'user'), access is granted
- Otherwise, access is denied
Best Practices
Role Design
- Keep the role hierarchy simple and clear
- Use descriptive role names that reflect their purpose (e.g.,
user,admin,moderator) - Use descriptive ability names that clearly indicate what they permit (e.g.,
edit,delete,view-logs) - Don't create too many roles - typically 3-5 roles are sufficient
- Build roles hierarchically by including lower-privilege roles in higher-privilege roles
- Group related abilities together logically (e.g., all billing-related abilities in billing management role)
Password Security
- Always use hashed passwords, never plain text
- Use TLS/HTTPS for all authentication traffic
- Implement password complexity requirements
- Consider password expiration policies for sensitive applications
- Use the cryptMakePassword API for production password hashing
User Management
- Implement user account lockout after failed login attempts
- Log authentication events for security monitoring
- Regularly audit user accounts and roles
- Remove inactive user accounts
- Use strong password requirements
APIs
The following APIs are available for user and role management:
- cryptMakePassword - Generate hashed password
- cryptCheckPassword - Verify password against hash
- webCanUser - Check if user has required role
- webGetUser - Get current authenticated user
- webGetRole - Get user's role
