Access Control Layers

The FlexGalaxy.AI platform uses three distinct layers of access control. Each layer answers a different question and is managed by a different persona.

Request arrives
  │
  ▼
┌──────────────────────────────────────────┐
│  Layer 1: Role (User-level)              │
│  "What is this user's job?"              │
│  Managed by: Account admin (AdminCenter) │
│  Stored in: identity provider (per-user roles) │
│  Example: admin, operator, viewer        │
└──────────────┬───────────────────────────┘
               │ User has required role?
               ▼
┌──────────────────────────────────────────┐
│  Layer 2: SCP (Account-level policy)     │
│  "What is this account allowed to call?" │
│  Managed by: Platform admin (SuperCrew)  │
│  Stored in: DotID authorization service  │
│  Example: deny thinghub:Thing:Enroll     │
└──────────────┬───────────────────────────┘
               │ SCP permits the action?
               ▼
┌──────────────────────────────────────────┐
│  Layer 3: Capability (Account-level)     │
│  "What is this account qualified to do?" │
│  Managed by: Platform admin (SuperCrew)  │
│  Stored in: DotID authorization service  │
│  Example: enroll_things, approve_licenses│
└──────────────┬───────────────────────────┘
               │ Account has capability?
               ▼
            Execute

Layer 1: Role

Question: What is this user’s job within this account?

Roles are user-level permissions managed by the account admin in AdminCenter. They determine what a specific person can do within their account’s resources.

Role

Can do

Cannot do

admin

Manage users, groups, policies, settings

N/A (full access within account)

operator

Enroll devices, join devices via access_code, manage assignments, create scopes

Manage users, change account settings

viewer

View devices, telemetry, reports

Modify anything

Roles are stored in the identity provider as realm roles or client roles. They are evaluated by each service before any authorization check.

Managed in: AdminCenter (tenant-facing)

Visible in: AdminCenter

Layer 2: Service Control Policy (SCP)

Question: What API actions is this account permitted to call?

SCPs are account-level policy boundaries — deny-based guardrails that restrict what actions an account can invoke, regardless of user roles or capabilities. They are the ceiling.

{
  "Version": "2024-01-01",
  "Statement": [
    {
      "Effect": "Deny",
      "Action": [
        "thinghub:Thing:Enroll",
        "thinghub:Thing:BulkEnroll"
      ],
      "Resource": "*"
    }
  ]
}

SCPs use the same policy document format as IAM policies (see Policy Document Format). They are evaluated at step 6 of the authorization evaluation algorithm (see Authorization Model).

Key properties:

  • Deny-based — SCPs define what is not allowed. If an SCP denies an action, it is blocked regardless of any other permission.

  • Account-scoped — each SCP applies to a specific account.

  • Inherited — in organizations, SCPs can be attached at the OU level and inherited by child accounts (future).

  • Cannot grant access — SCPs only restrict. An SCP that allows thinghub:* does not grant access; it merely does not deny it.

Managed in: SuperCrew (platform admin)

Visible in: AdminCenter (read-only), SuperCrew (full management)

Layer 3: Capability

Question: What is this account qualified to do?

Capabilities are account-level business qualifications — grant-based feature entitlements that represent verified trust. They are not action permissions; they are business prerequisites that certain operations check.

Capability

What it qualifies

Who typically has it

enroll_things

Register new devices in ThingHub

Verified device manufacturers

approve_licenses

Approve/issue licenses in TrustMint

Manufacturers, white-label partners

publish_marketplace

Publish products to Bazaar marketplace

Verified manufacturers

manage_ota_rollouts

Create and manage OTA rollouts in OTAForge

Manufacturers, authorized service partners

Key properties:

  • Grant-based — capabilities must be explicitly granted. Accounts start with no capabilities.

  • Account-scoped — capabilities belong to the account, not individual users. All users in the account benefit from the account’s capabilities.

  • Multiple — an account can have any combination of capabilities. They are not mutually exclusive.

  • Verified — granting a capability implies the platform has verified the account’s qualification (e.g., confirming they are a legitimate manufacturer).

  • Not action permissions — capabilities don’t say “you can call this API.” They say “you are qualified to perform this business function.” The API permission is handled by roles and SCPs.

Stored as a set of strings on the account in DotID authorization service:

Account
├── id: acc-xxx
├── name: "BROIT Robotics"
└── capabilities: ["enroll_things", "approve_licenses", "publish_marketplace"]

Managed in: SuperCrew (platform admin grants/revokes)

Visible in: AdminCenter (read-only — account admin can see what capabilities their account has)

How the Three Layers Interact

Example: User "alice" in account "BROIT" calls POST /api/v1/things (enroll)

Layer 1 — Role:
  Does alice have the "operator" or "admin" role?
  YES → proceed
  NO  → 403 Forbidden ("insufficient role")

Layer 2 — SCP:
  Does BROIT's SCP allow "thinghub:Thing:Enroll"?
  YES (no deny) → proceed
  NO (explicit deny) → 403 Forbidden ("action denied by policy")

Layer 3 — Capability:
  Does BROIT have the "enroll_things" capability?
  YES → proceed
  NO  → 403 Forbidden ("account not qualified — contact platform support")

All three passed → 201 Created

Role

SCP

Capability

Result

Reason

403

User lacks required role

Deny

403

Action denied by SCP

Allow

403

Account not qualified (no capability)

Allow

✓ Execute

All layers passed

Comparison

Aspect

Role

SCP

Capability

Question

What is your job?

What are you allowed to call?

What are you qualified to do?

Scope

User

Account

Account

Type

Permission

Guardrail (deny-based)

Entitlement (grant-based)

Managed by

Account admin

Platform admin

Platform admin

Managed in

AdminCenter

SuperCrew

SuperCrew

Visible in

AdminCenter

AdminCenter (read-only)

AdminCenter (read-only)

Analogous to

AWS IAM Role

AWS SCP

AWS service enablement

Default

No roles (no access)

No SCPs (everything allowed)

No capabilities (nothing qualified)

Service-Specific Capability Checks

Each service checks for the capability relevant to the operation:

Service

Operation

Required Capability

Without Capability

ThingHub

POST /things (enroll)

enroll_things

403 — “Join by Code instead”

ThingHub

POST /things/join

(none)

Any account can join

TrustMint

Approve license

approve_licenses

403

Bazaar

Publish product

publish_marketplace

403

OTAForge

Create / edit target filter

manage_ota_rollouts

403

OTAForge

Preview matched targets

manage_ota_rollouts

403

OTAForge

Create rollout

manage_ota_rollouts

403

OTAForge

View rollout status (own devices)

(none)

Any assigned account can see rollout status

Note: POST /things/join requires no capability — any account with a valid access_code can join. Viewing rollout status also requires no capability. Capabilities gate creation and management, not read access.

UI Visibility

SuperCrew (platform admin):

Account: BROIT Robotics (acc-xxx)

Service Control Policies
┌──────────────────────────────────────────┐
│ [DefaultAllow]  No restrictions           │
│ [+ Attach SCP]                            │
└──────────────────────────────────────────┘

Capabilities
┌──────────────────────────────────┬─────────┐
│ enroll_things                    │ [Revoke] │
│ approve_licenses                 │ [Revoke] │
│ publish_marketplace              │ [Revoke] │
│ manage_ota_rollouts              │ [Revoke] │
│                                  │          │
│ [+ Grant Capability]             │          │
└──────────────────────────────────┴─────────┘

AdminCenter (tenant admin, read-only):

Account Settings → Access & Capabilities

Service Control Policies (read-only)
┌──────────────────────────────────────────┐
│ No restrictions applied to this account.  │
└──────────────────────────────────────────┘

Capabilities (read-only)
┌──────────────────────────────────┬──────────┐
│ Enroll Things                    │ ● Active │
│ Approve Licenses                 │ ● Active │
│ Publish to Marketplace           │ ● Active │
│ Manage OTA Rollouts              │ ○ —      │
└──────────────────────────────────┴──────────┘

To request additional capabilities, contact platform support.