IAM (Identity & Access Management)
Identity and Access Management (IAM) in Hantera provides a comprehensive system for managing identities, roles, and permissions. IAM is the foundation for authentication and authorization across all Hantera services.
What is IAM?
IAM manages three core concepts:
- Identities - Who can access the system (principals and clients)
- Roles - What permissions identities have
- Sessions - Active authentication sessions
IAM provides REST APIs for creating and managing these entities, while the Graph API provides read access for querying identities.
Identity Types
Principal
A principal represents a human identity that authenticates with Hantera.
Key characteristics:
- Email address (used as username, must be unique)
- Password or OAuth authentication
- Can be assigned multiple roles
- Can be temporarily suspended
- Dynamic properties for custom data
When to use:
- Portal users (administrators, staff)
- Customer accounts
- Partner or vendor users
- Any human that needs to log in
Example:
{ "type": "principal", "properties": { "name": "John Admin", "phone": "+1234567890" }, "roles": ["system:portal:full"]}Client
A client represents an application or service identity for OAuth and API access.
Key characteristics:
- OAuth configuration (redirect URIs, grant types, scopes)
- Client secret authentication
- No password-based login
- System clients are protected from modification
When to use:
- Third-party integrations
- Mobile or web applications
- Service-to-service communication
- Webhook consumers
Example:
{ "type": "client", "properties": { "name": "Mobile App", "redirectUris": ["myapp://callback"], "grantTypes": ["authorization_code", "refresh_token"] }, "roles": []}System
A system identity represents internal Hantera processes.
Key characteristics:
- Not accessible via IAM APIs
- Used for background jobs and system operations
Role-Based Authorization
Built-in System Roles
Hantera provides built-in roles that use the system: namespace:
system:owner
Full administrative access to all Hantera resources and operations.
Capabilities:
- Manage all identities, roles, and permissions
- Access all resources without restrictions
- Configure system settings
- Perform destructive operations
system:portal:full
Complete access to the Hantera Portal and portal-managed resources.
Capabilities:
- Access all portal features
- Manage orders, customers, products
- View analytics and reports
- Configure portal settings
Typical users:
- Portal administrators
- Customer service managers
- Operations staff
Custom Roles
You can define custom roles with any namespace except system:.
Role naming pattern:
{namespace}:{capability}Examples:
store:manager- Store management permissionssupport:agent- Customer support accesswarehouse:operator- Warehouse operationsreporting:viewer- Read-only reporting access
Custom role definition:
{ "key": "support:agent", "description": "Customer support representative", "acl": { "entries": [ { "resource": "actors", "permission": "*" }, { "resource": "graph", "permission": "*" }, { "resource": "registry", "permission": "read" }, ] }}Role-Based Categorization
Roles serve dual purposes in Hantera:
- Authorization - Define what an identity can do
- Categorization - Group identities by function
This means you can filter identities by role prefix to create semantic groups:
// Get all portal usersGET /resources/iam/principals?rolePrefix=system:portal:
// Get all support agentsGET /resources/iam/principals?rolePrefix=support:
// Get all store managersGET /resources/iam/principals?rolePrefix=store:This pattern eliminates the need for separate “user type” fields while ensuring categorization always reflects actual permissions.
List API Features
The IAM list endpoints support comprehensive filtering, search, and cursor-based pagination for efficient data retrieval.
Cursor-Based Pagination
All list endpoints use cursor-based pagination for optimal performance with large datasets:
Query parameters:
limit- Items per page (default: 50, max: 100)after- Cursor for next pagebefore- Cursor for previous page
Response format:
{ "principals": [...], "hasMore": true, "nextCursor": "01933e8f-7c45-7123-9abc-123456789abc", "prevCursor": "01933e8f-7c45-7123-9abc-123456789abc"}Example - First page:
GET /resources/iam/principals?limit=50Example - Next page:
GET /resources/iam/principals?limit=50&after=01933e8f-7c45-7123-9abc-123456789abcSearch Capabilities
Principals - Search by name or email:
GET /resources/iam/principals?search=johnClients - Search by name:
GET /resources/iam/clients?search=mobileRoles - Search by key or description:
GET /resources/iam/roles?search=adminSearch is case-insensitive and matches partial strings.
Filtering Options
Principals:
# Filter by multiple roles (OR logic)GET /resources/iam/principals?roles=system:owner&roles=system:portal:full
# Include suspended principalsGET /resources/iam/principals?includeSuspended=true
# Backward compatible role prefixGET /resources/iam/principals?rolePrefix=system:portal:Clients:
# Filter by client typeGET /resources/iam/clients?type=service_account
# Include suspended clientsGET /resources/iam/clients?includeSuspended=trueRoles:
# Exclude system rolesGET /resources/iam/roles?includeSystem=falseSorting
All list endpoints support sorting:
Principals:
# Sort by name ascendingGET /resources/iam/principals?sortBy=name&sortDirection=asc
# Sort by email descendingGET /resources/iam/principals?sortBy=email&sortDirection=desc
# Sort by created dateGET /resources/iam/principals?sortBy=created&sortDirection=descClients:
# Available sort fields: name, type, createdGET /resources/iam/clients?sortBy=name&sortDirection=ascRoles:
# Available sort fields: name (key), descriptionGET /resources/iam/roles?sortBy=description&sortDirection=ascCombined Queries
You can combine search, filters, sorting, and pagination:
GET /resources/iam/principals?search=admin&roles=system:portal:full&sortBy=name&limit=20This query:
- Searches for “admin” in name/email
- Filters by
system:portal:fullrole - Sorts by name
- Returns 20 results per page
Principal Suspension
Principals can be suspended to temporarily block authentication without deleting the account.
Suspension vs Deletion
| Feature | Suspension | Deletion |
|---|---|---|
| Reversible | ✅ Yes | ❌ No |
| Data retained | ✅ Yes | ❌ No |
| Can authenticate | ❌ No | ❌ No |
| Roles retained | ✅ Yes | ❌ No |
| Visible in API | ❌ No (by default) | ❌ No |
Suspension Workflow
-
Suspend the principal
POST /resources/iam/principals/{id}/suspend- Sets suspension timestamp
- Automatically revokes all active sessions
- Principal cannot create new sessions
-
Principal attempts to log in
- Authentication fails with “suspended” status
- Error message: “Account has been suspended”
-
Reactivate when ready
POST /resources/iam/principals/{id}/reactivate- Clears suspension timestamp
- Principal can authenticate again
- Must log in to create new sessions
When to Use Suspension
Appropriate uses:
- Security incidents (compromised account)
- Policy violations (temporary punishment)
- Account review periods
- Inactive account cleanup (temporary)
- Employee leave of absence
Not appropriate:
- Permanent account removal (use deletion instead)
- Password changes (use password reset)
- Role changes (update roles directly)
Protected System Roles
Roles in the system: namespace cannot be modified or deleted via API:
system:ownersystem:portal:full
You can:
- ✅ Assign system roles to principals
- ✅ Remove system role assignments
You cannot:
- ❌ Modify system role permissions
- ❌ Delete system roles
- ❌ Create new roles with
system:prefix
Access Attributes (ABAC)
Access attributes enable Attribute-Based Access Control (ABAC), allowing you to scope permissions to specific data.
Use case: A store manager should only access orders and inventory for their assigned locations.
Solution: Set channelKey attributes on the identity:
{ "accessAttributes": { "channelKey": ["STORE-NYC", "STORE-BOS"] }}When this identity accesses resources, they can only view/modify data where the resource’s channelKey matches one of their attribute values. Attempting to access other channels returns 403 Forbidden.
Password Management
Password Reset Flow
Password resets generate temporary passwords that expire on first use:
-
Administrator initiates reset
POST /resources/iam/principals/{id}/password/reset -
API returns temporary password
{"temporaryPassword": "TempPass123"} -
Administrator sends email to user
Use the Sendings API to send the temporary password:
POST /resources/sendings{"category": "password_reset","subject": "Password Reset","bodyHtml": "<p>Your temporary password is: TempPass123</p>"} -
User logs in with temporary password
- Session is created but marked as requiring password change
-
User must change password
POST /resources/me/password{"currentPassword": "TempPass123","newPassword": "NewSecurePass456!"}
Password Requirements
Passwords must meet these criteria:
- Minimum 8 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one digit
- No common/weak passwords
Email Uniqueness
Email addresses must be unique across all principals. Attempting to create a principal with an existing email address will return an error:
{ "error": { "code": "EMAIL_NOT_UNIQUE", "message": "Email address already in use" }}Authorization Model
Required Permissions
IAM operations require specific permissions:
Principal management:
iam/principals:read # List and get principalsiam/principals:write # Create and update principalsiam/principals:delete # Delete principalsClient management:
iam/clients:read # List and get clientsiam/clients:write # Create and update clientsiam/clients:delete # Delete clientsRole management:
iam/roles:read # List and get rolesiam/roles:write # Create and update custom rolesiam/roles:delete # Delete custom rolesSafe Updates with ETags
IAM APIs use ETags to prevent conflicting updates when multiple users modify the same identity.
Usage:
# 1. Get the identity (response includes ETag header)GET /resources/iam/principals/{id}
# 2. Update with If-Match header using the ETagPUT /resources/iam/principals/{id}If-Match: "etag-value-from-step-1"{ "properties": { ... }}If someone else modified the identity between your GET and PUT, the request will fail with 409 Conflict, preventing you from accidentally overwriting their changes.
API Endpoints
IAM provides REST endpoints organized by resource type:
/resources/iam/principals/*- Principal management/resources/iam/clients/*- Client management/resources/iam/roles/*- Role management
For complete endpoint documentation, request/response formats, and error codes, see the HTTP API Reference.
Integration Patterns
Creating Portal Users
PUT /resources/iam/principals/{userId}{ "properties": { "name": "John Admin", }, "roles": ["system:portal:full"]}Then generate a temporary password and send via email using the Sendings API.
Role-Based Filtering
GET /resources/iam/principals?rolePrefix=system:portal:Returns only principals with portal access, useful for building user management UIs.
Suspension Management
POST /resources/iam/principals/{userId}/suspendImmediately blocks authentication and revokes all sessions. Reactivate with:
POST /resources/iam/principals/{userId}/reactivateRelated Resources
- Identity Graph Node - Query identities via Graph
- Access Control - Permission patterns and best practices
- Sendings API - Send emails (for password resets)