The SC Platform's security model follows three core principles:
This security model is what makes the platform safe to extend. When proactive agents arrive, they inherit this same permission system — no new security infrastructure required. A background agent monitoring the Permian Basin area only sees Permian Basin data because it runs with a scoped identity, just like a human user would.
The platform supports exactly two authentication methods. There is no third option, no fallback, and no exception.
All human users authenticate via Microsoft Entra ID (Azure AD) using PKCE-based OAuth 2.0. This applies to every tool in the ecosystem — Ask Ricky, Pennywise, Hawkeye, Ops Dashboard, Platform Admin.
User row maps them to tenant + roleMachine-to-machine callers (agents, connectors, external integrations) use sk_-prefixed API keys.
ApiKey row in the databaseApiKeyScope rows — each key can only do what its scopes allow| Property | Entra ID (Humans) | API Keys (Machines) |
|---|---|---|
| Token type | JWT (signed by Microsoft) | Opaque sk_ string |
| Identity binding | User row (Entra OID → tenant + role) | ApiKey row (hash → tenant + scopes) |
| Scope source | User's group/role membership | ApiKeyScope rows on the key |
| Management | Entra ID / Azure Portal | Platform Admin |
| Revocation | Entra token expiry + revocation | Delete key in Platform Admin |
Every domain table in the platform has a tenantId column. Every database query filters by it. This is the foundational security boundary:
ctx: { tenantId, principal, logger } as its first argument — tenant isolation is structural, not optionalUsers are assigned a role that determines their feature-level access. The hierarchy is strictly ordered:
| Role | Access Level | Typical User |
|---|---|---|
| MEMBER | Standard data access within their scoped boundaries. Can use tools, submit feedback, view data they're authorized to see. | Mechanics, area managers, analysts |
| TENANT_ADMIN | Everything a MEMBER can do, plus tenant configuration: manage users, configure integrations, manage API keys within their tenant. | IT leads, department heads |
| SUPER_ADMIN | Cross-tenant access. Can create tenants, manage the platform itself, configure global settings. | Platform development team |
Each API route declares exactly one guard — requireMember, requireTenantAdmin, or requireSuperAdmin. There is no "check both" ambiguity.
Scopes are the fine-grained permissions that control what data a caller can access. Unlike roles (which are about feature access), scopes are about data access — specifically, which categories of data a caller can read or act on.
| Scope | What It Gates | Used By |
|---|---|---|
Agent.Run |
Permission to start an AI agent conversation at all | Ask Ricky |
Telemetry.Read |
Live sensor data, fault codes, alarms from M-Link / Enbase | Ask Ricky, Ops Dashboard |
Assets.Read |
Equipment profiles — unit makeup, specs, configuration | Ask Ricky, Ops Dashboard |
WorkHistory.Read |
Past maintenance records, corrective maintenance items | Ask Ricky |
KnowledgeBase.Read |
Curated troubleshooting guides and general knowledge | Ask Ricky |
Directory.Read |
Employee/mechanic directory for dispatch lookup | Ask Ricky |
FleetLocation.Read |
Real-time vehicle GPS positions from Samsara | Ops Dashboard |
KnowledgeBase.Write |
Create and modify knowledge base articles | Ricky Curator |
Tenant.Admin |
Tenant configuration, user management, API key management | Platform Admin |
ApiKeyScope rows when the key is created. A key with only Telemetry.Read cannot access work orders, regardless of what code calls it.This is where the platform's permission model becomes uniquely powerful. When the AI Engine receives a request from Ask Ricky:
Telemetry.Read, the "Get Telemetry" tool doesn't exist for that agent session — Claude can't even try to call itMost AI platforms bolt security on after the fact — a blanket API key with broad access. The SC Platform inverts this: the AI never has more access than the person (or identity) it represents. Security isn't a layer around the agent — it's woven into how the agent is constructed for each request.
Beyond scopes (which gate categories of data), some tools enforce row-level filtering based on the user's organizational assignment.
Pennywise has the strictest row-level controls in the ecosystem because it handles sensitive financial data:
Hawkeye uses the org chart to determine what approval items a manager sees:
| Tool | Auth Method | Scope Model | Data Filtering |
|---|---|---|---|
| Ask Ricky | Entra ID (PKCE) | Platform scopes → AI tool gating | Per-unit data access via scopes |
| Pennywise | Entra ID (PKCE) | Role + scope assignment | Row-level RBAC (region/area/unit) |
| Hawkeye | Entra ID (PKCE) | Org chart-based visibility | Reports chain filtering |
| Ops Dashboard | Entra ID (PKCE) | Platform scopes | Scope-filtered API responses |
| TrueCount | Entra ID (PKCE) | Platform scopes | Warehouse assignment |
| Platform Admin | Entra ID (PKCE) | TENANT_ADMIN / SUPER_ADMIN role | Tenant-scoped management |
| AI Engine | Inherits from caller | Caller's scopes → tool composition | Tool-level + data-level filtering |
The permission model is managed through two primary interfaces: