Merchant user management
Use this runbook to diagnose and change merchant access from the Support Portal at support.peakpos.co. Merchant users sign in at portal.peakpos.co.
This page covers merchant identities. Peak Support staff and agent identities use separate Identity Platform tenants, support IAM, invitation flows, and management permissions. Never add a merchant to the Support Portal, or a support user to a merchant organization, to work around authorization.
Access model
Access is the combination of:
- an active merchant user;
- organization membership;
- optional store membership;
- one or more IAM roles;
- the groups and policies reachable from those roles; and
- product entitlements required by the requested feature.
Roles are not a universal hierarchy. Authorization evaluates the requested resource and action. An explicit matching deny wins; otherwise a matching permit allows; otherwise the decision is deny. Store membership gates remain in front of store-scoped IAM checks.
Seeded merchant roles
| Role | Scope | Current purpose |
|---|---|---|
org_owner | Organization | Primary ownership and the full seeded permission catalog |
org_admin | Organization | Full seeded permission catalog without ownership semantics |
org_member | Organization | Basic organization/profile, membership-read, invitation-read, and limited self-service access |
store_admin | Store | Full seeded permissions for the assigned store plus permitted organization-level features |
store_manager | Store | Operational management for the assigned store |
stocker | Store | Inventory receiving and adjustment, serialized inventory, transfers, and self-shift access |
store_user | Store | Transaction-capable frontline access for the assigned store |
Do not use retired labels such as org_manager or cashier as if they were
current system roles. Do not infer permissions from a display label.
Custom organization roles and groups may grant a different effective
permission set.
Roles, groups, and policies
The canonical relationship is:
user -> roles -> groups -> permit/deny policies
Roles and groups are organization-owned. A role may be organization-scoped or store-scoped; scope is fixed when the role is created. The merchant Access page can create custom groups, attach permission policies, create roles, attach groups, and assign roles. These operations require organization-admin authorization; Support must not manufacture a custom role to make an error disappear.
Which surface owns the change?
| Surface | Appropriate work | Authorization boundary |
|---|---|---|
| Support Portal Client Users | View organization users/owners/invites, invite a member or owner, revoke/resend a pending invite, enable/disable a merchant user, set a staff PIN | mgmt.orgs.read for viewing; mgmt.orgs.write for mutations |
| Support Portal Access / Canonical IAM permissions | Diagnose the effective role-to-permission matrix and list users by role | Read-only view; mgmt.orgs.read |
| Retail Portal Staff | Merchant-owned organization and store roster, invitations, membership, and role assignment | Exact org.members.*, store.members.*, and org.admin permission checks |
| Retail Portal Access | Merchant-owned IAM groups, roles, policies, and assignments | org.admin plus the page's membership-read gates |
| Support Portal Staff | Peak Support identities and support invitations | Support IAM (mgmt.users.read for lists and mgmt.admin.admin for mutations); never merchant IAM |
Agent-accessible management routes still enforce the agent's portfolio and sale floor. A route being visible in the portal does not mean every support role or agent can mutate it.
Diagnose before changing anything
Collect:
- exact sign-in email and Firebase/merchant user ID when available;
- organization ID and intended organization role;
- store ID(s) and intended store role(s);
- failing page or action;
- effective permission key reported by the UI or API;
- current invite status and expiry;
- whether the user is active;
- whether the relevant product is enabled.
Then:
- Open the client in the Support Portal.
- Open Client Users.
- Enable Show inactive users when the identity is missing from the default view.
- Confirm the email, status, organization role, last login, and latest pending invite.
- Use the read-only canonical IAM permissions view to verify the required permission and which role grants it.
- For store-scoped failures, have the merchant verify store membership and store-role assignment in the Retail Portal.
Do not promote a user to org_admin simply because a page returned 403. First
identify the denied resource/action, store membership, and feature entitlement.
Invite an organization member
In Client Users:
- Select Invite User.
- Choose Member.
- Enter the exact email, first name, and last name.
- Send the invite.
- Confirm a new pending invite appears with role
org_member.
The member invitation establishes organization membership. It does not assign a store or a store-scoped role. The merchant must add the accepted user to the correct store and assign an appropriate store role when store access is needed.
Invite an organization owner
Owner access has ownership semantics and the full seeded permission catalog. Confirm authorization from the merchant before proceeding.
- Select Invite User.
- Choose Owner.
- Verify the email and legal contact name.
- Send the invite.
- Confirm the pending invite and, after acceptance,
org_ownermembership.
Use the onboarding pipeline's final welcome action for the first owner of a new client. Use Client Users for later, explicitly approved ownership changes.
Revoke or resend an invitation
Only pending invitations are shown in the pending list.
- Revoke invalidates the selected invitation.
- Resend is implemented as revoke followed by creation of a new invitation and token.
After a resend, the user must use the newest link. Confirm that the old invite is no longer pending and the new invite has a later creation/expiry time.
If invite creation succeeds but email delivery is delayed, do not create several concurrent invites. Check spelling, spam/quarantine, delivery status, and the current pending row first.
Enable or disable a merchant user
Disable preserves historical records but prevents sign-in. This changes the merchant user's active state; it is not a store-membership removal. Confirm the security or offboarding request and check whether the user participates in other stores or organizations before disabling.
Prefer the narrowest merchant-owned change:
- remove a store membership to remove access to one store;
- change a role assignment to change permissions;
- remove organization membership to remove one organization;
- disable the user only for account-wide security/offboarding needs.
Use Enable only after the reason for disablement is resolved. Re-open the page and verify the user is active.
Do not deactivate the last org_owner. The merchant IAM service protects the
last owner during organization membership removal; treat any ownership
reassignment as an approved, auditable change.
Set a POS staff PIN
The Support Portal can set a merchant user's numeric PIN through the organization user record. The current contract accepts 4–8 digits.
- Verify the selected organization and user.
- Select Set PIN.
- Enter the new PIN through the portal.
- Confirm the save succeeds.
- Have the merchant verify the intended store login.
Do not place a PIN in tickets or chat. Setting a PIN does not add store membership or grant transaction permissions.
Verification matrix
| Intended result | Evidence |
|---|---|
| User can enter the organization | Active user, accepted latest invite, organization membership present |
| User can enter a store | Organization membership plus membership in that exact store |
| User can perform an action | Required resource/action is permitted by an assigned role; no matching deny |
| User can see a portal page | IAM requirement and product entitlement are both satisfied |
| Owner handoff complete | Active org_owner, latest invite accepted, correct organization visible |
| Support mutation authorized | Signed-in support principal has the required mgmt.* permission |
Common failures
Invite accepted but the organization is missing
Confirm the user signed in with the invited email, used the latest invitation, and is active. Verify organization membership. Do not solve this by assigning a store role; store membership cannot replace organization membership.
Organization is visible but a store is missing
Verify membership in the exact store and the role's store scope. An organization role does not create an arbitrary store membership.
Page is hidden or an action returns 403
Record the required permission from the portal configuration or controller, then inspect effective roles/groups/policies and product entitlement. A hidden page can be an entitlement gate even when IAM is correct.
User remains unable to sign in after Enable
Confirm the user record is active, the Firebase email matches, the email is verified when required, and the latest invitation completed. Escalate identity tenant or Firebase binding failures; do not create a duplicate merchant user.
Support user cannot mutate Client Users
The support principal may have mgmt.orgs.read without mgmt.orgs.write, or an
agent may be outside the client's portfolio/sale floor. Request the exact
management permission or correct assignment rather than using a broader
support role by name.
Escalate with user ID, email, organization/store IDs, invite ID and status, active flag, assigned role IDs/scopes, denied permission, entitlement, and the exact response. Exclude PINs, invitation tokens, Firebase tokens, and other credentials.