The problem
Increasingly, the credential that grants AI access belongs to a person, not to a deployment.
Developers hold seat subscriptions (ChatGPT Pro, Claude Max, Copilot) that sit mostly idle, while the same person separately pays per-token for API access from their own apps. The obvious ask is "let my applications use the seat I already have."
Busbar today assumes the other model: a provider has one credential (api_key), resolved once at startup, and every caller's traffic spends it. That is correct for "the company pays". It does not express "each person's own subscription pays".
This issue is to work out what Busbar should do about that. Opening it because the question came up in #41 and the answer is bigger than that thread.
What works today
upstream_credentials: passthrough. The calling application runs its own sign-in flow, holds and refreshes the user's token, and presents it per request. Busbar forwards it upstream instead of using its own key.
This is shipped, and it is arguably the right layering. The credential belongs to whoever owns the user's session, and the app already has the browser, the login UI and the refresh timer. Busbar keeps routing, failover, metering and policy. Governance is unaffected: Busbar still authenticates the caller with its own key, so per-user budgets, rate limits, pool restrictions and cost visibility all still work.
Two things it cannot do:
- Act when the user is absent. No background job or scheduled agent working on someone's behalf, because there is no stored credential to use.
- Work with off-the-shelf clients. Cursor, VS Code and similar know how to send an API key. They do not implement OAuth, and they should not have to.
What is missing, and what is actually blocked
Worth separating these, because only one of them is blocked and it is not the expensive one.
The credential lifecycle. Provider-agnostic, and buildable today:
- per-caller credential storage, encrypted at rest
- refresh-before-expiry with single-flight (when a token expires and N requests notice at once, exactly one refresh should happen and the rest wait on it)
- per-caller credential selection on the request path, cheap enough not to move the latency numbers
- per-caller failure isolation, so one user revoking consent fails that user's requests rather than the pool
- a "connect an account" completion for the hosted sign-in flow Busbar already has
A specific provider's OAuth client. Needs a client registration and a public endpoint from that provider.
Busbar already ships the OAuth ceremony itself: authorization-code with PKCE, state and nonce validated before identity is established, callback handling, and a multi-hop token-exchange loop, all behind the kind: auth plugin ABI. It is currently pointed inbound. It is how a developer signs in to Busbar and gets their own budgeted key (see token exchange). Pointing equivalent machinery outbound is real work, but it is not from scratch.
So the honest framing: the expensive part is the credential lifecycle, and nobody is blocking it.
One thing we will not do
Where subscription-backed access works today for third-party tools, it generally works by presenting a vendor's own first-party client identity and calling a product backend rather than the public API. We are not going to ship that. If the only way to obtain a credential for a given provider is to impersonate that provider's own client, then that provider is unsupported and we will say so, rather than putting operators on the wrong side of an agreement they did not read.
If a provider offers a genuine third-party path for subscription-backed access, we would support it.
What we would like input on
- Is the absent-user case the real requirement for you, or is passthrough enough? This is the question that decides whether this is worth building.
- Where should credentials live? Busbar's governance store, or delegated to a
kind: secret plugin so operators choose (Vault, cloud secret managers).
- What should happen when a refresh fails mid-flight? Fail that caller's requests only, fall back to the deployment's own key, or refuse to start.
- Does anyone need this for a provider that already offers per-user API keys, rather than OAuth? That is a strictly easier version of the same feature and might be worth doing first.
- What are we missing?
No timeline on this yet. Comments and use cases welcome, especially concrete ones, since the absent-user question above is the deciding factor.
The problem
Increasingly, the credential that grants AI access belongs to a person, not to a deployment.
Developers hold seat subscriptions (ChatGPT Pro, Claude Max, Copilot) that sit mostly idle, while the same person separately pays per-token for API access from their own apps. The obvious ask is "let my applications use the seat I already have."
Busbar today assumes the other model: a provider has one credential (
api_key), resolved once at startup, and every caller's traffic spends it. That is correct for "the company pays". It does not express "each person's own subscription pays".This issue is to work out what Busbar should do about that. Opening it because the question came up in #41 and the answer is bigger than that thread.
What works today
upstream_credentials: passthrough. The calling application runs its own sign-in flow, holds and refreshes the user's token, and presents it per request. Busbar forwards it upstream instead of using its own key.This is shipped, and it is arguably the right layering. The credential belongs to whoever owns the user's session, and the app already has the browser, the login UI and the refresh timer. Busbar keeps routing, failover, metering and policy. Governance is unaffected: Busbar still authenticates the caller with its own key, so per-user budgets, rate limits, pool restrictions and cost visibility all still work.
Two things it cannot do:
What is missing, and what is actually blocked
Worth separating these, because only one of them is blocked and it is not the expensive one.
The credential lifecycle. Provider-agnostic, and buildable today:
A specific provider's OAuth client. Needs a client registration and a public endpoint from that provider.
Busbar already ships the OAuth ceremony itself: authorization-code with PKCE,
stateandnoncevalidated before identity is established, callback handling, and a multi-hop token-exchange loop, all behind thekind: authplugin ABI. It is currently pointed inbound. It is how a developer signs in to Busbar and gets their own budgeted key (see token exchange). Pointing equivalent machinery outbound is real work, but it is not from scratch.So the honest framing: the expensive part is the credential lifecycle, and nobody is blocking it.
One thing we will not do
Where subscription-backed access works today for third-party tools, it generally works by presenting a vendor's own first-party client identity and calling a product backend rather than the public API. We are not going to ship that. If the only way to obtain a credential for a given provider is to impersonate that provider's own client, then that provider is unsupported and we will say so, rather than putting operators on the wrong side of an agreement they did not read.
If a provider offers a genuine third-party path for subscription-backed access, we would support it.
What we would like input on
kind: secretplugin so operators choose (Vault, cloud secret managers).No timeline on this yet. Comments and use cases welcome, especially concrete ones, since the absent-user question above is the deciding factor.