Metadata-Version: 2.5
Name: segmentstream-connections-runtime
Version: 0.1.0a3
Summary: Private OAuth connection runtime for SegmentStream workspaces
Project-URL: Homepage, https://segmentstream.com
Author: SegmentStream
License-Expression: Apache-2.0
License-File: LICENSE
License-File: NOTICE
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: <3.14,>=3.12
Requires-Dist: fastapi<1,>=0.117
Requires-Dist: pydantic<3,>=2.10
Requires-Dist: segmentstream-pipeline==0.1.0a8
Requires-Dist: uvicorn<1,>=0.35
Description-Content-Type: text/markdown

# SegmentStream connections runtime

`segmentstream-connections-runtime` is the private Cloud Run host for custom
OAuth 2.0 connections authored with the SegmentStream SDK. It loads the
workspace's `connections/connections.py` tuple named `connections`, resolves
customer-owned secret references, and performs authorization-code and
refresh-token exchanges. Token responses are written directly to a pre-created,
per-authorization-attempt Google Secret Manager secret; the HTTP API returns
credential metadata and never token values.

The runtime is an infrastructure component, not a public user-facing API. Its
Cloud Run service must require IAM authentication.

```shell
python -m segmentstream_connections_runtime inspect manifest.json
python -m segmentstream_connections_runtime serve
```

The server listens on `PORT`, defaulting to `8080`. A declaration such as
`secret_ref("google-oauth-client-id")` is resolved from
`SEGMENTSTREAM_CONNECTION_SECRET_GOOGLE_OAUTH_CLIENT_ID` in the isolated runtime
environment. Client secrets use the same mapping convention.

Serving also requires `SEGMENTSTREAM_GOOGLE_CLOUD_PROJECT` and Cloud Run's
automatically injected `K_REVISION`. The Cloud Run service identity obtains a
short-lived access token from the Google metadata server and must have
`secretmanager.versions.add` and `secretmanager.versions.access` only for each
managed `ss-oauth-<authorization-attempt-id>` secret. The control plane creates
the secret and its IAM policy before completing OAuth authorization.

Every authorization, exchange, and refresh request includes the deployment's
`runtimeRevision`. The runtime compares it with `K_REVISION` before resolving
secrets or calling an OAuth provider and returns
`409 runtime_revision_mismatch` if Cloud Run routed the stable service URL to a
different revision. `POST /internal/v1/connections/{key}/token/exchange` also
accepts an authorization-attempt ID, its deterministic credential secret ID,
the effective `configurationDigest`, authorization code, redirect URI, and PKCE
verifier. The credential envelope binds its schema-v2 payload to the attempt,
connection key, and configuration digest. `POST .../token/refresh` accepts the
authorization-attempt ID, credential secret ID, and exact stored version. Both
token operations return only `credentialVersion`,
`tokenType`, `expiresAt`, `scopes`, and `hasRefreshToken`.

A deterministic token response that is malformed, omits a required refresh
token, or grants fewer scopes than the selected connection is rejected as
`400 oauth_token_response_invalid` before a credential version is written.
Definitive provider 4xx rejections return `400 oauth_provider_rejected`, while
timeouts, rate limits, transport failures, and provider 5xx responses remain
`502 oauth_provider_unavailable` so an ambiguous exchange can be recovered.

## Releases

Releases use the version in `pyproject.toml` and are published from the
`connections-runtime-v<version>` Git tag by the protected
`connections-runtime-release.yml` workflow. PyPI releases are immutable, so the
package version must be incremented before creating another release tag.
