Roles & permissions (RBAC)
Every human who signs in to the Helium MVNE dashboard holds one operator-scoped role. The role fixes what that person can see and do across your subscribers, billing, catalog, and operator configuration. Roles are assigned when you invite a teammate (or change their role later) from Settings → Team.
Scope. This page covers dashboard team members, the humans on your operator. It is not about API keys. Server-to-server integrations authenticate with operator API keys, which are full-access within your operator and scoped by their own capability tags (see Authentication). The roles below govern people, not keys.
The role catalogue
Read top to bottom as a descending-privilege ladder.
| Role | Summary |
|---|---|
| Owner | Full control: team, integrations, API keys, billing. One per operator. |
| Admin | Manage everything, including API keys, webhooks, and carrier connections. |
| Viewer | Read-only across subscriber, plan, and usage data. No PII. |
| Basic support (Tier 1) | Read-only across subscriber data; PII after CPNI step-up. No writes. |
| High-level support (Tier 2) | Edit subscribers, SIMs, and ports (incl. lifecycle); PII + changes after CPNI step-up. |
| Marketing | Read-only catalogue and subscriber overview for campaigns. No PII. |
| Accounting / Finance | Read-only billing: invoices, payments, refunds. No PII. |
| Billing support | Manage invoices, payments, refunds, and subscriptions; PII after CPNI step-up. |
| Legal / Compliance | Full subscriber access incl. PII (no step-up) for legal holds and data requests. |
Only owner and admin can manage the team (invite members, change roles) and reach operator configuration: API keys, webhook endpoints, and carrier connections. No other role can mint a key or rotate a carrier credential.
The matrix
Each cell lists what the role can do across that group of resources.
A dash (—) means no access.
| Role | Subscribers | Subscriptions | SIMs & ports | Billing | Plans & add-ons | API keys & config |
|---|---|---|---|---|---|---|
| Owner | View, PII, Edit, Delete | View, Edit, Lifecycle | View, Edit, Lifecycle, Cancel | View, Edit, Create, Pay, Void, Delete | View, Edit, Delete | View, Edit, Rotate, Test, Delete |
| Admin | View, PII, Edit, Delete | View, Edit, Lifecycle | View, Edit, Lifecycle, Cancel | View, Edit, Create, Pay, Void, Delete | View, Edit, Delete | View, Edit, Rotate, Test, Delete |
| Viewer | View | View | View | — | View | — |
| Basic support | View, PII (step-up), CPNI verify | View | View | View | View | — |
| High-level support | View, PII (step-up), CPNI verify, Edit | View, Edit, Lifecycle | View, Edit, Lifecycle, Cancel | View | View | — |
| Marketing | View | View | — | — | View | — |
| Accounting / Finance | View | View | — | View | View | — |
| Billing support | View, PII (step-up), CPNI verify | View, Edit | — | View, Create, Pay, Void | View | — |
| Legal / Compliance | View, PII, Edit, Delete | View | View | View | View | — |
A few capabilities don't fit the grid above:
- Operator settings: read for every role; write for owner and admin only.
- Event log: owner and admin see the operator-wide event
firehose (
events:read_all). The support, finance, and legal tiers see object-scoped activity timelines only (events:read); viewer and marketing see neither. - Team management: owner and admin only.
Action vocabulary
The grid's friendly verbs map to these underlying permissions, expressed
as resource:action strings.
| Verb | Permission | Meaning |
|---|---|---|
| View | read | List and view records (non-PII fields only). |
| PII | read_pii | View full PII (email, phone, date of birth) with no step-up. |
| PII (step-up) | read_pii_cpni | View PII after a per-subscriber CPNI step-up. |
| CPNI verify | cpni:verify | Issue and submit a CPNI step-up challenge. |
| Edit | write | Create and update records. |
| Create | create | Create a payment or refund. |
| Pay / Void | invoices:pay / invoices:void | Pay or void an invoice. |
| Lifecycle | lifecycle | Drive state-machine transitions (subscriptions, SIMs). |
| Cancel | ports:cancel | Cancel a port request. |
| Rotate | connections:rotate | Rotate carrier-connection credentials. |
| Test | test | Use sandbox test helpers / send test webhooks. |
| Delete | delete | Delete records. |
PII & the CPNI step-up
Subscriber PII (email, phone, date_of_birth) is gated by role.
Access splits three ways:
- Full PII, no step-up: owner, admin, and legal/compliance hold
subscribers:read_pii. They always see PII. - PII via CPNI step-up: the support and billing tiers hold
subscribers:read_pii_cpni. They see redacted records by default and must pass a per-subscriber CPNI verification before PII unlocks or any change is allowed. - No PII: viewer, marketing, and accounting/finance hold plain
read. PII stays redacted topii_redacted, always.
For roles in bucket 3, and for bucket-2 roles without an active grant,
the three PII fields come back null with pii_redacted: true on
subscriber reads, lists, and search.
How step-up works
A step-up challenge is a one-time code the subscriber reads back to the agent. The full loop:
- The agent requests a challenge on a single subscriber, from that
subscriber's detail page. The platform generates a one-time code,
stores it encrypted, and emits a
cpni.verification.requestedwebhook. - You deliver the code to the subscriber over a channel you own (see below).
- The subscriber reads the code back to the agent over whatever channel the support conversation is happening on.
- The agent submits the code. On a match, the agent earns a time-bounded grant for that subscriber.
The grant is keyed to that agent and that one subscriber. While it's active:
- that subscriber's PII renders in full for that agent, and
- mutations on the subscriber (and resources that resolve to it: subscriptions, SIMs, ports, invoices, addresses, payment methods) are permitted.
Lists and search have no single subject, so they stay redacted for
step-up roles; agents unlock subscribers one at a time from the detail
page. A step-up role that tries to view PII or mutate without a grant
gets a cpni_step_up_required error.
How the code reaches the subscriber
Helium MVNE never contacts your subscribers directly; by design it has no channel to them (subscribers are records, not auth principals). So the one-time code is handed to you, and you deliver it however you already reach that subscriber.
- The code rides on the webhook. It's delivered as the
codefield on thecpni.verification.requestedevent's object. This is a secure, delivery-only field: the code is injected into the outbound webhook at send time and is never written to the event store, so it can't be read back from the events API or from a webhook redelivery once the code window closes. See Webhooks. - You relay it to the subscriber over a channel you own (SMS, email, push notification, your mobile app), exactly as you'd send any one-time passcode. Helium MVNE doesn't pick the channel; you do.
- The subscriber reads it back to the agent through whatever support channel the conversation is already in: a chat tool, SMS, a voice call, and so on. The agent enters it to complete the challenge.
The net effect: the code only ever travels channels you control, and only the agent who requested it can submit it. Helium MVNE never touches your subscriber-contact channels.
Assigning roles
- Roles are set from Settings → Team when you invite a member or change an existing member's role.
- Owner is never handed out from the team picker; ownership transfer is a separate, deliberate action.
- If you use enterprise SSO, an IdP can map a newly provisioned user onto any role except owner and admin. A self-asserted IdP attribute must never mint API-key or carrier-credential access; elevating someone to owner/admin stays a deliberate in-dashboard action by an existing admin.