Outgoing OAuth: promotion path from SaaS to core¶
Goal: Outgoing OAuth (third-party API credentials, OAuth link flow, refresh) is a core single-user capability. Incoming browser OAuth (GitHub login, tenant identity) stays SaaS enterprise UI + control plane only.
Do not conflate auth planes: outbound provider auth ≠ MCP transport keys ≠ execute JWT identity (see Incoming auth and Appliance persistence).
Current state¶
| Concern | Location |
|---|---|
| OAuth token/link logic | plasm-runtime (hosted_oauth_kv, oauth_client), plasm-agent-core (oauth_link_catalog, oauth_link_session, outbound_secret_provider) |
| Link + outbound-secret HTTP (hosted product) | Implemented in the composed hosted binary (outside this OSS tree). |
| Control-plane contract | Automation uses /internal/oauth-link/v1/* and /internal/outbound-secrets/v1/* with the deployment control-plane secret (not documented on this site). |
| Hosted UI | Plasm Cloud (platform.plasm.tools) provides OAuth provider registration and outbound connection flows that target those surfaces. |
| Pure OSS binary | PlasmHostState.saas == None — no /internal/*; outbound today is limited unless extended |
Target seam¶
- Mount outgoing OAuth HTTP on OSS data plane — Move or duplicate the public link/callback and secret write surfaces from
plasm-saasintoplasm-agent-coreHTTP (http.rs/ dedicated module), gated for single-user / local use (e.g. localhost, shared local secret, or file-based allowlist — exact policy is a follow-on implementation task). - Keep SaaS control-plane variants — Hosted deployments may keep
/internal/* for Phoenix automation; contract doc remains the integrator surface. - Fence incoming OAuth — GitHub login,
IncomingAuthController,http_incoming_tenant, and workspace binding remain inweb/+plasm-saasonly. - Phoenix as composer — Ops/project UIs continue to call core or
/internal/* to upsert providers and secrets; they do not own the OAuth protocol implementation.
Migration notes¶
- Shared header auth for
/internal/*lives inplasm-agent-core[control_plane_http.rs](https://github.com/ryan-s-roberts/plasm-core/blob/main/crates/plasm-agent-core/src/control_plane_http.rs); OSS-mounted outgoing routes need a different gate. PlasmSaaSHostExtensioncurrently wiresoauth_link_catalogandoutbound_secret_provider; pure OSS may need the same types attached toPlasmOssHostStateor a minimal extension without tenant MCP — seeserver_state.rsinplasm-agent-core.