Authorization
Peak Gateway uses two authorization models: OAuth2 scopes for API clients (machine-to-machine) and Firebase roles for portal users (human users).
Rename note: gateway's current management model is Organization -> Location. Legacy OAuth claims and management paths still use
merchantnaming in a few places as compatibility aliases; thosemerchantIdvalues identify concrete location records.
Rename guardrails
Safe statements:
- OAuth claim names such as
global_merchant_accessandmerchant_idsare still live compatibility surfaces - those legacy
merchant_idsvalues identify concrete location records - portal and SDK app state should still prefer organization/location language
Unsafe statements:
- that OAuth scopes or claims have fully renamed away from
merchantwording - that
merchant_idsimplies a separate tenant model from locations - that new client-facing docs should introduce fresh
merchant*app-state names
OAuth2 Scopes (API Clients)
API clients authenticate via OAuth2 client_credentials flow with the auth service, then use Bearer tokens with scoped access.
| Scope | Description | Endpoints |
|---|---|---|
txn:process | Process payment transactions (sale, auth, capture, void, refund, tip-adjust, enrich) | POST /api/v1/transactions/* on processing |
session:create | Create online checkout sessions and hosted payment forms | POST /api/v1/checkout/sessions, POST /api/v1/hosted/* on online-txn |
merchant:activate | Activate payment processors for merchants | POST /api/v1/merchants/{id}/activate-transit on management |
provision:request | Request and manage merchant onboarding jobs | /api/v1/provisioning/jobs/* on merchant-onboarding |
batch:manage | Manage settlement batches (retry stuck, force-close) | POST /api/v1/settlements/{id}/retry, POST /api/v1/settlements/{id}/force-close on processing |
admin:* | Wildcard admin access, grants all scopes | All endpoints across all services |
admin:* controls scopes, not portal roles. Legacy merchant-targeting claims are independent of scopes:
global_merchant_access=truemeans the client can act across all locationsglobal_merchant_access=falsemeans the client is restricted to the explicitmerchant_idslist
Token claims use snake_case (global_merchant_access, merchant_ids), while management API payloads and portal DTOs use camelCase (globalMerchantAccess, merchantIds) for the same fields.
An OAuth client with admin:* and global_merchant_access=true can access every location. A client with admin:*, global_merchant_access=false, and merchant_ids=["loc_123"] still only has location access for loc_123.
Docs-side closeout for the rename is reached when this page is read as:
- scopes describe capability
- legacy
merchant_*claims describe location targeting on the wire - legacy
merchant_*role names are compatibility labels for organization/location-scoped access - organization/location terminology remains the preferred model everywhere else
Typical Client Configurations
| Client Type | Scopes |
|---|---|
| POS Terminal | txn:process, batch:manage |
| E-Commerce Integration | session:create, txn:process |
| Device Management System | provision:request |
| Admin Dashboard | admin:* |
Registering an OAuth Client
- Admin Portal → OAuth Clients → Register
- Assign scopes matching the client's use case
- Choose whether the client has global merchant access:
- set
globalMerchantAccess=truefor cross-location access - set
globalMerchantAccess=falseand providemerchantIdsto restrict the client to explicit locations - avoid leaving
merchantIdsempty unless the client is intentionally supposed to have no location access
- set
- Note the
client_idandclient_secret - Client calls
POST /auth/oauth2/tokenwithgrant_type=client_credentialson the public gateway domain
Portal Roles (Firebase Auth)
Portal users authenticate via Firebase Auth (Google SSO or SAML). Roles are hierarchical, higher ranks include all lower rank permissions.
| Role | Rank | Description |
|---|---|---|
super_admin | 0 | Full access including SAML SSO configuration and user deletion |
admin | 1 | Full operational access across organizations, locations, users, transactions, and settlements |
merchant_admin | 2 | Legacy role label for a location-scoped operator who manages assigned organization/location settings, users, transactions, and subscriptions |
merchant_user | 3 | Legacy role label for a location-scoped portal user with read-heavy access to assigned organization/location data |
readonly | 4 | Read-only access to assigned organization/location data |
The role names merchant_admin and merchant_user remain part of the current
claim and API shape, but they should be read as compatibility labels for
organization/location-scoped portal access, not as proof of a separate
merchant-first tenant model.
Authorization Annotations
Services enforce authorization via two primary authorization patterns:
@RequireScope("txn:process"): Used on controllers that serve API clients (processing, online-txn, merchant-onboarding)@RequireManagementPermission(...): Used on management controllers for portal users and backed byManagementAuthorizer
OAuth clients are not promoted into Firebase-style portal roles. Merchant targeting comes from OAuth token merchant claims, while management permissions remain role-based unless an endpoint explicitly opts into OAuth scope checks.
The scope checks live in libs/security, while management permission enforcement lives under services/management/.../security.
Endpoint Authorization Matrix
Auth Service
| Method | Path | Auth |
|---|---|---|
GET | /health | Public |
POST | /api/v1/clients | Admin (super_admin, admin) |
GET | /api/v1/clients | Admin (super_admin, admin) |
DELETE | /api/v1/clients/{clientId} | Admin (super_admin, admin) |
GET | /api/v1/me | Authenticated |
Processing Service
| Method | Path | Scope |
|---|---|---|
POST | /api/v1/transactions/sale | txn:process |
POST | /api/v1/transactions/auth | txn:process |
POST | /api/v1/transactions/{id}/capture | txn:process |
POST | /api/v1/transactions/{id}/void | txn:process |
POST | /api/v1/transactions/{id}/refund | txn:process |
POST | /api/v1/transactions/{id}/tip-adjust | txn:process |
POST | /api/v1/subscriptions | txn:process |
GET | /api/v1/settlements | batch:manage |
POST | /api/v1/settlements/{id}/retry | batch:manage |
Management Service
Most management endpoints remain portal-role-based. The OAuth-exposed paths are the explicit exceptions below.
| Method | Path | Min Role |
|---|---|---|
POST | /api/v1/merchants | admin |
GET | /api/v1/merchants | readonly |
PUT | /api/v1/merchants/{id} | merchant_admin |
POST | /api/v1/saml-providers | super_admin |
GET | /api/v1/audit-log | admin |
Management Service (OAuth exceptions)
| Method | Path | Scope |
|---|---|---|
POST | /api/v1/merchants/{merchantId}/activate-transit | merchant:activate |
GET | /api/v1/event-subscriptions | admin:* |
GET | /api/v1/event-subscriptions/{subscriptionId} | admin:* |
POST | /api/v1/event-subscriptions | admin:* |
PUT | /api/v1/event-subscriptions/{subscriptionId} | admin:* |
DELETE | /api/v1/event-subscriptions/{subscriptionId} | admin:* |
Online-Txn Service
| Method | Path | Auth |
|---|---|---|
POST | /api/v1/checkout/sessions | session:create |
POST | /api/v1/checkout/sessions/{id}/pay | Public |
POST | /api/v1/tokens | session:create |
POST | /api/v1/api-keys | Merchant auth |
GET | /api/v1/webhooks/events | Public |
Merchant-Onboarding Service
| Method | Path | Scope |
|---|---|---|
POST | /api/v1/provisioning/jobs | provision:request |
GET | /api/v1/provisioning/jobs/{id} | provision:request |