Skip to content
OpenSmartRoute
Skillv1.0.0

maintainx-enterprise-rbac

Configure enterprise role-based access control for MaintainX integrations. Use when implementing SSO, managing organization-level permissions, or setting up enterprise access controls with MaintainX.

by jeremylongshore(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from jeremylongshore/tons-of-skills-marketplace (plugins/saas-packs/maintainx-pack/skills/maintainx-enterprise-rbac/SKILL.md). Install upstream with npx skills add jeremylongshore/tons-of-skills-marketplace --skill maintainx-enterprise-rbac. Copyright stays with the author (MIT).

MaintainX Enterprise RBAC

Overview

Configure enterprise role-based access control for MaintainX integrations with role definitions, location-scoped permissions, and audit logging.

Prerequisites

  • MaintainX Enterprise plan
  • Understanding of RBAC concepts
  • Node.js 18+

MaintainX Role Hierarchy

Organization Admin
├── can manage all locations, users, teams, and settings
├── Full API access
│
Location Manager
├── can manage work orders, assets at assigned locations
├── API: filtered by locationId
│
Technician
├── can view/update assigned work orders
├── API: filtered by assigneeId
│
Viewer (Read-Only)
└── can view work orders, assets, locations
    └── API: GET endpoints only

Instructions

Step 1: Role Definitions

// src/rbac/roles.ts

export type Role = 'admin' | 'manager' | 'technician' | 'viewer';

interface Permission {
  resource: string;
  actions: Array<'create' | 'read' | 'update' | 'delete'>;
  scope?: 'all' | 'location' | 'assigned';
}

export const ROLE_PERMISSIONS: Record<Role, Permission[]> = {
  admin: [
    { resource: 'workorders', actions: ['create', 'read', 'update', 'delete'], scope: 'all' },
    { resource: 'assets', actions: ['create', 'read', 'update', 'delete'], scope: 'all' },
    { resource: 'locations', actions: ['create', 'read', 'update', 'delete'], scope: 'all' },
    { resource: 'users', actions: ['create', 'read', 'update', 'delete'], scope: 'all' },
    { resource: 'teams', actions: ['create', 'read', 'update', 'delete'], scope: 'all' },
  ],
  manager: [
    { resource: 'workorders', actions: ['create', 'read', 'update'], scope: 'location' },
    { resource: 'assets', actions: ['create', 'read', 'update'], scope: 'location' },
    { resource: 'locations', actions: ['read'], scope: 'location' },
    { resource: 'users', actions: ['read'], scope: 'all' },
    { resource: 'teams', actions: ['read'], scope: 'all' },
  ],
  technician: [
    { resource: 'workorders', actions: ['read', 'update'], scope: 'assigned' },
    { resource: 'assets', actions: ['read'], scope: 'location' },
    { resource: 'locations', actions: ['read'], scope: 'location' },
  ],
  viewer: [
    { resource: 'workorders', actions: ['read'], scope: 'all' },
    { resource: 'assets', actions: ['read'], scope: 'all' },
    { resource: 'locations', actions: ['read'], scope: 'all' },
  ],
};

Step 2: Permission Middleware

// src/rbac/middleware.ts
import express from 'express';

interface AuthContext {
  userId: number;
  role: Role;
  locationIds: number[];  // Locations this user can access
}

function authorize(resource: string, action: 'create' | 'read' | 'update' | 'delete') {
  return (req: express.Request, res: express.Response, next: express.NextFunction) => {
    const auth = req.user as AuthContext;
    if (!auth) return res.status(401).json({ error: 'Not authenticated' });

    const perms = ROLE_PERMISSIONS[auth.role];
    const match = perms.find(
      (p) => p.resource === resource && p.actions.includes(action),
    );

    if (!match) {
      return res.status(403).json({
        error: 'Insufficient permissions',
        required: { resource, action },
        role: auth.role,
      });
    }

    // Apply scope filtering
    if (match.scope === 'location') {
      req.query.locationId = auth.locationIds.join(',');
    } else if (match.scope === 'assigned') {
      req.query.assigneeId = String(auth.userId);
    }

    next();
  };
}

// Usage in routes
const router = express.Router();

router.get('/api/workorders', authorize('workorders', 'read'), async (req, res) => {
  const client = new MaintainXClient();
  const { data } = await client.getWorkOrders(req.query as any);
  res.json(data);
});

router.post('/api/workorders', authorize('workorders', 'create'), async (req, res) => {
  const client = new MaintainXClient();
  const { data } = await client.createWorkOrder(req.body);
  res.json(data);
});

Step 3: Scoped API Keys

Create separate API keys per role to enforce server-side access control:

// src/rbac/scoped-clients.ts

const scopedClients: Record<Role, MaintainXClient> = {
  admin: new MaintainXClient(process.env.MAINTAINX_API_KEY_ADMIN),
  manager: new MaintainXClient(process.env.MAINTAINX_API_KEY_MANAGER),
  technician: new MaintainXClient(process.env.MAINTAINX_API_KEY_TECH),
  viewer: new MaintainXClient(process.env.MAINTAINX_API_KEY_VIEWER),
};

function getClientForRole(role: Role): MaintainXClient {
  const client = scopedClients[role];
  if (!client) throw new Error(`No client configured for role: ${role}`);
  return client;
}

Step 4: User and Team Management

// Fetch all users and their roles
async function listUsersWithRoles(client: MaintainXClient) {
  const { data } = await client.getUsers({ limit: 100 });
  const { data: teams } = await client.request('GET', '/teams');

  const userTeams = new Map<number, string[]>();
  for (const team of teams.teams) {
    for (const member of team.members || []) {
      const existing = userTeams.get(member.id) || [];
      existing.push(team.name);
      userTeams.set(member.id, existing);
    }
  }

  for (const user of data.users) {
    const teamList = userTeams.get(user.id) || [];
    console.log(`  ${user.firstName} ${user.lastName} (${user.email})`);
    console.log(`    Role: ${user.role || 'N/A'} | Teams: ${teamList.join(', ') || 'None'}`);
  }
}

Step 5: Audit Logging

// src/rbac/audit.ts
function logAccess(auth: AuthContext, resource: string, action: string, result: 'allow' | 'deny') {
  const entry = {
    timestamp: new Date().toISOString(),
    type: 'access_control',
    userId: auth.userId,
    role: auth.role,
    resource,
    action,
    result,
    locationScope: auth.locationIds,
  };
  // Send to your log aggregation (CloudWatch, Datadog, etc.)
  console.log(JSON.stringify(entry));
}

Output

  • Role definitions mapping roles to resource permissions and scopes
  • Express middleware enforcing RBAC on all API proxy routes
  • Location-scoped and assignee-scoped query filtering
  • Scoped API keys per role for defense in depth
  • Audit logging for all access control decisions

Error Handling

Issue Cause Solution
403 on valid user Missing permission for action Check ROLE_PERMISSIONS mapping
Empty results for manager Location scope filter too narrow Verify locationIds in auth context
Scoped key missing Environment variable not set Add MAINTAINX_API_KEY_{ROLE} to env
Audit log gaps Middleware not applied to route Ensure authorize() is on all routes

Resources

Next Steps

For complete platform migration, see maintainx-migration-deep-dive.

Examples

Check if a user can perform an action:

function canPerform(role: Role, resource: string, action: string): boolean {
  const perms = ROLE_PERMISSIONS[role];
  return perms.some((p) => p.resource === resource && p.actions.includes(action as any));
}

console.log(canPerform('technician', 'workorders', 'update'));  // true
console.log(canPerform('technician', 'workorders', 'delete'));  // false
console.log(canPerform('viewer', 'workorders', 'read'));        // true

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/jeremylongshore-tons-of-skills-marketplace-maintainx-ent-805e27/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

jeremylongshore-tons-of-skills-marketplace-maintainx-ent-805e27.ocm.jsonjson
{
  "ocm": "1",
  "id": "jeremylongshore-tons-of-skills-marketplace-maintainx-ent-805e27",
  "kind": "skill",
  "name": "maintainx-enterprise-rbac",
  "description": "Configure enterprise role-based access control for MaintainX integrations. Use when implementing SSO, managing organization-level permissions, or setting up enterprise access controls with MaintainX. Trigger with phrases like \"maintainx rbac\", \"maintainx sso\", \"maintainx enterprise\", \"maintainx permissions\", \"maintainx roles\".",
  "publisher": "jeremylongshore",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "general"
    ],
    "tags": [
      "skill-md",
      "saas",
      "maintainx",
      "rbac",
      "skills-sh"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Configure enterprise role-based access control for MaintainX integrations. Use when implementing SSO, managing organization-level permissions, or setting up enterprise access controls with MaintainX. Trigger with phrases like \"maintainx rbac\", \"maintainx sso\", \"maintainx enterprise\", \"maintainx permissions\", \"maintainx roles\"."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "skills.sh",
      "repository": "https://github.com/jeremylongshore/tons-of-skills-marketplace",
      "path": "plugins/saas-packs/maintainx-pack/skills/maintainx-enterprise-rbac/SKILL.md",
      "ref": "HEAD",
      "url": "https://github.com/jeremylongshore/tons-of-skills-marketplace/blob/HEAD/plugins/saas-packs/maintainx-pack/skills/maintainx-enterprise-rbac/SKILL.md",
      "key": "jeremylongshore/tons-of-skills-marketplace/plugins/saas-packs/maintainx-pack/skills/maintainx-enterprise-rbac/SKILL.md"
    },
    "compatibility": "Designed for Claude Code",
    "allowed_tools": [
      "Read,",
      "Write,",
      "Edit,",
      "Bash(npm:*)"
    ],
    "license": "MIT"
  },
  "instructions": "# MaintainX Enterprise RBAC\n\n## Overview\n\nConfigure enterprise role-based access control for MaintainX integrations with role definitions, location-scoped permissions, and audit logging.\n\n## Prerequisites\n\n- MaintainX Enterprise plan\n- Understanding of RBAC concepts\n- Node.js 18+\n\n## MaintainX Role Hierarchy\n\n```\nOrganization Admin\n├── can manage all locations, users, teams, and settings\n├── Full API access\n│\nLocation Manager\n├── can manage work orders, assets at assigned locations\n├── API: filtered by locationId\n│\nTechnician\n├── can view/update assigned work orders\n├── API: filtered by assign",
  "cost": {
    "context_tokens": 1871
  }
}

Fetch it by URL: GET /api/v1/registry/jeremylongshore-tons-of-skills-marketplace-maintainx-ent-805e27/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.