Forward to an external router
You may not want to run provider billing at all. Someone else — a platform, a reseller, your own central IT — runs a router with the accounts on it, and your agents reach models through theirs.
The question that usually stops this arrangement is: do they then get my customer list?
They do not have to, and whether they do is decided by who runs the router, not by the protocol:
| who runs the router | do they see your users? | how calls are made |
|---|---|---|
| an LLM provider or platform | no, and they have no reason to. They meter you as one account | your agents call out opaque, and their router leaves requireIdentifiedCaller off |
| your own company, hooked to Bedrock, Azure or similar | yes, deliberately. You are accountable for your own people and want to see which user each call was for | callers are identified, and the router sets requireIdentifiedCaller: true |
Both are normal. The rest of this page is mostly the first case, where the operator is someone else; the second is your own router and is covered in Run your own.
The two identities in play
Section titled “The two identities in play”Your router forwards under its own HexaEight identity: the external operator authorises your router, once, and that is the party they have a relationship with and bill.
There is no token to carry. Your router proves itself cryptographically, with its identity, on every call. That is the credential. The
authandsecretfields in an upstream entry exist for ordinary providers — Bedrock, OpenAI and the like, which issue API keys — and an entry that forwards to another HexaEight router leavesauthat its default,none.
Whether your individual users are named to them is your choice.
Opaque callers
Section titled “Opaque callers”Your agent decides this, per call. Where it would normally put the person it is acting for,
it puts the literal :opaque: instead. Nothing is configured on the external router, and nothing is
configured in advance — it is a choice made in the request:
| your agent sends | the external router meters |
|---|---|
forUser: [email protected] | per caller — they see alice |
forUser: :opaque: | per agent — they see only you |
With :opaque:, per-caller accounting stays inside your agent, where your callers are actually
known. The external router meters your agent as one customer.
Why this is safe rather than a loophole
Section titled “Why this is safe rather than a loophole”Nothing is weakened by it:
- the relaying agent is a real identity that was already authorised
- it is the party the external router has a relationship with and bills
- the stored subject is the agent, so every log and downstream meter says so plainly
Nobody is misled. The trade is explicit and yours to make: choose opacity, and the external router gates and meters per agent instead of per person.
A customer roster should not have to be disclosed to a model provider as the price of routing through one.
What each side controls
Section titled “What each side controls”| you | the external operator | |
|---|---|---|
| provider keys | — | holds them |
| which models are available | request | decides |
| who your end users are | know them | need not |
| per-user metering | yours, locally | per your agent |
| revoking one of your users | your policy | not involved |
Your users are admitted, metered and revoked by your agent’s policy. The external operator authorises the identity that calls them — your agent when it calls out directly, or your router when you run one in between — once, and never sees a person behind it.
If you are the external operator
Section titled “If you are the external operator”Running the router that others forward into, you want the opposite of a self-hosted deployment:
- accept opaque callers — leave
requireIdentifiedCalleroff. Turning it on requires every customer to disclose their user list to you, which most will refuse and none of them need to do - authorise per calling identity — that agent or router is your customer
- meter per calling identity — it is what you can bill
A company running a router for its own staff wants the reverse of all three, because the people on the other side are its own: see Run your own.
A self-hosted router usually sets requireIdentifiedCaller: true; an external one usually must not.
The two deployments want opposite things, and the setting is how you say which you are.
Setting it up
Section titled “Setting it up”What you need from them
Section titled “What you need from them”The operator of the external router gives you two things:
| its URL | where their router listens |
| admission | they add the identity that will call them to their policy, once — your agent, or your router if you run one in between |
They do not need your user list, and you do not need an account with their model providers.
Point a route at them
Section titled “Point a route at them”Forwarding is just an upstream whose URL is their router instead of a provider. In your own
upstreams.yaml:
upstreams: - match: "partner-*" # a route name you choose shape: "anthropic" # the API your engines speak url: "https://their-router.example.com/v1/messages" auth: "none" # your router's identity IS the credentialThen seal an engine against it exactly as you would any other route:
hexaeight-activate engine --add chat \ --name chat \ --model "partner-sonnet|<their model id>" \ --router "<your-router-identity>|http://127.0.0.1:5100"Your agents still talk only to your router. It decides which calls leave.
Choosing whether to name your users
Section titled “Choosing whether to name your users”Opacity is the calling agent’s choice, made per request: it either sends the user’s subject as
forUser, or sends :opaque:.
forUser: <sha512 of the user's email> they meter per personforUser: :opaque: they meter per agent - your list stays yoursAnd the receiving operator decides whether opacity is allowed at all, with one line in their
upstreams.yaml:
requireIdentifiedCaller: true # refuses opaque callers outrightIf you are the external operator, leave that off. Turning it on requires every customer to disclose their user list to you as the price of routing through you.
Both at once
Section titled “Both at once”Nothing stops you running your own router for some routes and forwarding others. Agents name a route; where that route resolves is the router’s business. Moving a model from your account to a partner’s — or back — changes no agent configuration.