docs

Roles & permissions (RBAC)

Every human who signs in to the heliumOS 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.

RoleSummary
OwnerFull control: team, integrations, API keys, billing. One per operator.
AdminManage everything, including API keys, webhooks, and carrier connections.
ViewerRead-only across subscriber, plan, and usage data. No PII.
Basic support (Tier 1)Read across subscriber data, plus the collection actions, lifting a payment-method block, stopping a scheduled cancellation, and a guarded number change; PII after CPNI step-up.
High-level support (Tier 2)Edit subscribers, SIMs, and ports (incl. lifecycle); PII + changes after CPNI step-up.
MarketingRead-only catalogue and subscriber overview for campaigns. No PII.
Accounting / FinanceRead-only billing: invoices, payments, refunds. No PII.
Billing supportManage invoices, payments, refunds, and subscriptions; PII after CPNI step-up.
Legal / ComplianceFull 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.

RoleSubscribersSubscriptionsSIMs & portsBillingPlans & add-onsAPI keys & config
OwnerView, PII, Edit, DeleteView, Edit, Lifecycle, Stop cancellation, Immediate downgradeView, Edit, Lifecycle, CancelView, Edit, Create, Pay, Void, DeleteView, Edit, DeleteView, Edit, Rotate, Test, Delete
AdminView, PII, Edit, DeleteView, Edit, Lifecycle, Stop cancellation, Immediate downgradeView, Edit, Lifecycle, CancelView, Edit, Create, Pay, Void, DeleteView, Edit, DeleteView, Edit, Rotate, Test, Delete
ViewerViewViewViewView
Basic supportView, PII (step-up), CPNI verify, Lift payment blockView, Stop cancellationView, Change numberViewView
High-level supportView, PII (step-up), CPNI verify, Edit, Lift payment blockView, Edit, Lifecycle, Stop cancellation, Immediate downgradeView, Edit, Lifecycle, CancelViewView
MarketingViewViewView
Accounting / FinanceViewViewViewView
Billing supportView, PII (step-up), CPNI verifyView, Edit, Stop cancellationView, Create, Pay, VoidView
Legal / ComplianceView, PII, Edit, DeleteViewViewViewView

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.
  • Forcing a downgrade: a plan downgrade normally takes effect at the subscriber's renewal, so they keep the service they have paid for. Owner, admin, and high-level support can override that and apply it on the spot (apply_immediately on switch_plan), which credits the subscriber nothing for the rest of the period. This is a dashboard-only capability: an operator API key cannot use it, whatever its scopes, because it relays your subscribers' own plan changes as well as your agents'.

Action vocabulary

The grid's friendly verbs map to these underlying permissions, expressed as resource:action strings.

VerbPermissionMeaning
ViewreadList and view records (non-PII fields only).
PIIread_piiView full PII (email, phone, date of birth) with no step-up.
PII (step-up)read_pii_cpniView PII after a per-subscriber CPNI step-up.
CPNI verifycpni:verifyIssue and submit a CPNI step-up challenge.
EditwriteCreate and update records.
CreatecreateCreate a payment or refund.
Pay / Voidinvoices:pay / invoices:voidPay or void an invoice.
LifecyclelifecycleDrive state-machine transitions (subscriptions, SIMs).
Change numbersims:change_msisdnHave the carrier assign the line a new number. Held on its own (without sims:lifecycle) it is guarded: the number cannot have been ported in, the line cannot have been renumbered in the last 90 days, and the caller cannot choose the new number. Each refusal points at a role holding lifecycle.
Stop cancellationsubscriptions:uncancelCall off a cancellation booked for the end of the billing period, so the subscription renews as normal. Satisfied by lifecycle as well.
Lift payment blocksubscribers:payment_block_clearLift the 24-hour hold that stops a subscriber saving a card after a high-risk decline.
Immediate downgradesubscriptions:downgrade_immediatelyApply a plan downgrade now instead of at the subscriber's renewal, with nothing credited back.
Cancelports:cancelCancel a port request.
Rotateconnections:rotateRotate carrier-connection credentials.
TesttestUse sandbox test helpers / send test webhooks.
DeletedeleteDelete records.

PII & the CPNI step-up

Subscriber PII (email, phone, date_of_birth) is gated by role. Access splits three ways:

  1. Full PII, no step-up: owner, admin, and legal/compliance hold subscribers:read_pii. They always see PII.
  2. 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.
  3. No PII: viewer, marketing, and accounting/finance hold plain read. PII stays redacted to pii_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:

  1. 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.requested webhook.
  2. You deliver the code to the subscriber over a channel you own (see below).
  3. The subscriber reads the code back to the agent over whatever channel the support conversation is happening on.
  4. 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

heliumOS 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 code field on the cpni.verification.requested event'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. heliumOS 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. heliumOS 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.