Skip to content

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:

  1. Identities - Who can access the system (principals and clients)
  2. Roles - What permissions identities have
  3. 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",
"email": "[email protected]",
"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 permissions
  • support:agent - Customer support access
  • warehouse:operator - Warehouse operations
  • reporting: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:

  1. Authorization - Define what an identity can do
  2. Categorization - Group identities by function

This means you can filter identities by role prefix to create semantic groups:

// Get all portal users
GET /resources/iam/principals?rolePrefix=system:portal:
// Get all support agents
GET /resources/iam/principals?rolePrefix=support:
// Get all store managers
GET /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 page
  • before - 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=50

Example - Next page:

GET /resources/iam/principals?limit=50&after=01933e8f-7c45-7123-9abc-123456789abc

Search Capabilities

Principals - Search by name or email:

GET /resources/iam/principals?search=john

Clients - Search by name:

GET /resources/iam/clients?search=mobile

Roles - Search by key or description:

GET /resources/iam/roles?search=admin

Search 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 principals
GET /resources/iam/principals?includeSuspended=true
# Backward compatible role prefix
GET /resources/iam/principals?rolePrefix=system:portal:

Clients:

# Filter by client type
GET /resources/iam/clients?type=service_account
# Include suspended clients
GET /resources/iam/clients?includeSuspended=true

Roles:

# Exclude system roles
GET /resources/iam/roles?includeSystem=false

Sorting

All list endpoints support sorting:

Principals:

# Sort by name ascending
GET /resources/iam/principals?sortBy=name&sortDirection=asc
# Sort by email descending
GET /resources/iam/principals?sortBy=email&sortDirection=desc
# Sort by created date
GET /resources/iam/principals?sortBy=created&sortDirection=desc

Clients:

# Available sort fields: name, type, created
GET /resources/iam/clients?sortBy=name&sortDirection=asc

Roles:

# Available sort fields: name (key), description
GET /resources/iam/roles?sortBy=description&sortDirection=asc

Combined Queries

You can combine search, filters, sorting, and pagination:

GET /resources/iam/principals?search=admin&roles=system:portal:full&sortBy=name&limit=20

This query:

  • Searches for “admin” in name/email
  • Filters by system:portal:full role
  • 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

FeatureSuspensionDeletion
Reversible✅ Yes❌ No
Data retained✅ Yes❌ No
Can authenticate❌ No❌ No
Roles retained✅ Yes❌ No
Visible in API❌ No (by default)❌ No

Suspension Workflow

  1. Suspend the principal

    POST /resources/iam/principals/{id}/suspend
    • Sets suspension timestamp
    • Automatically revokes all active sessions
    • Principal cannot create new sessions
  2. Principal attempts to log in

    • Authentication fails with “suspended” status
    • Error message: “Account has been suspended”
  3. 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:owner
  • system: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:

  1. Administrator initiates reset

    POST /resources/iam/principals/{id}/password/reset
  2. API returns temporary password

    {
    "temporaryPassword": "TempPass123"
    }
  3. 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>"
    }
  4. User logs in with temporary password

    • Session is created but marked as requiring password change
  5. 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 principals
iam/principals:write # Create and update principals
iam/principals:delete # Delete principals

Client management:

iam/clients:read # List and get clients
iam/clients:write # Create and update clients
iam/clients:delete # Delete clients

Role management:

iam/roles:read # List and get roles
iam/roles:write # Create and update custom roles
iam/roles:delete # Delete custom roles

Safe 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 ETag
PUT /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",
"email": "[email protected]"
},
"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}/suspend

Immediately blocks authentication and revokes all sessions. Reactivate with:

POST /resources/iam/principals/{userId}/reactivate