Skip to main content

Identity mapping: principal to billing account

Vluna maintains a 1:1 mapping between your principal_id and Vluna's billing_account_id within a realm.

In most integrations, principal_id should simply be the most stable billing-owner identifier you already have. Keep the first integration simple.

Rules (contract)

  • The mapping is immutable after first creation.
  • The first time Vluna sees a new principal_id, it creates and binds a billing_account_id.
  • Treat billing_account_id as sensitive. Do not trust it from untrusted clients.
  • Choose principal_id carefully. It should represent the entity that owns billing in your system, not just the current auth or collaboration context.

Choosing principal_id

Start with the simplest stable identifier you already have:

  • If billing is per-user, use a stable user id.
  • If billing is shared by an org, team, or workspace, use that stable org/team/workspace id.

You only need a separate internal billing-owner id when your ownership model is more complex, for example when users can later move from personal billing to shared org billing, or can join someone else's org while keeping separate billing ownership.

If you are unsure, ask: "Who is the long-lived billing owner for these charges?" Use that identifier as principal_id.

Even if the mapping can be created lazily, prefetch it in your backend:

  1. User signs in or your backend receives a customer-scoped request.
  2. Your backend calls POST /mgt/v1/token/issue with principal_id.
  3. Vluna returns:
    • billing_account_id
    • a short-lived bearer token
  4. Your backend stores principal_id -> billing_account_id in your database.

Why this helps:

  • You validate connectivity early.
  • You avoid "first-request creates mapping" surprises in critical paths.
  • You get a stable foreign key into Vluna data for support and analytics.

What to store in your database

At minimum:

  • principal_id (string)
  • billing_account_id (uuid string)
  • realm_id (string)
  • timestamps: created_at, updated_at

Next