Skip to main content

Connect Portal API

Billerang has two separate control planes, each with its own API and its own auth model.

Tenant API vs. Connect portal

Tenant /api/v1 is the billing engine API for a single tenant environment (a WildFly deployment): sellers, customers, catalog, orders, invoices, and so on. It authenticates with an OAuth 2.0 client-credentials bearer token from Keycloak and is meant for server-to-server calls and the tenant frontend. See Billerang v1 API.

Connect portal /api/portal/* is the org-level control plane: it manages users, roles, groups, profiles, organization settings, environments, and security policy (SSO, 2FA, password policy) across every tenant environment an organization owns. It is a separate Go service (billerang-connect-portal), not part of the WildFly backend.

An organization can own multiple tenant environments (sandbox, staging, production). The Connect portal is where an org administrator manages people and access across all of them; the tenant /api/v1 IAM surface manages roles and groups inside a single tenant. Both write into the same Keycloak realm (billerang), at different scopes.

Auth model difference

Tenant /api/v1Connect portal /api/portal/*
CredentialOAuth 2.0 bearer token (client credentials grant)Browser session cookie (OIDC login)
ScopingTenant, resolved from the API hostOrganization, resolved from the subdomain
Typical callerServer-to-server integration, tenant frontendConnect portal single-page app in a browser
Elevated actionsRole-based (Keycloak client roles)Same, plus a portal-specific connect:org-admin role gate on security endpoints

The Connect portal has no server-to-server bearer-token flow today. A caller logs in via GET /auth/login, which redirects to Keycloak scoped to the org derived from the subdomain ({org}.connect.billerang.com), and GET /auth/callback sets an encrypted, HTTP-only session cookie. Every subsequent /api/portal/* call must carry that cookie, and a middleware check rejects the request if the subdomain's org does not match the session's org claim.

Reference

The full endpoint-by-endpoint reference (every route, request/response shape, and try-it-out) is at /portalApiReference, an embedded Scalar viewer over portal-v1.yaml.

This spec documents the routes as they exist today under /api/portal/*. Some paths use verb-in-path actions and mixed key types that don't match the tenant /api/v1 naming conventions; each operation in the spec carries an x-v1-target extension showing the planned normalized path under a future /api/portal/v1/* scheme (not live yet). See docs/adr/ADR-connect-portal-api.md in the repository for the full rationale.