Design: identity in both directions. OAuth 2.1, token exchange, durable consent, and webhooks that make Flowstate a principled hub
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 9
- Forks
- 0
- Avg merge
- 3h 3m
- Merged PRs (30d)
- 509
Description
Owner direction, grounded against the tree at aae30e7. The thesis: Flowstate sits in a sweet spot (more than a Makefile, less than a full language, durable underneath) and modern auth is how it becomes a hub rather than an island: runs that act on behalf of humans and systems, receive events from anywhere, and hand work to anything, without ever holding a long-lived credential. Pillar P2 in #336's map; satellites #243 (WIF gaps), #159 (triggers), #173 (credential invisibility ladder), #108 (MCP both directions).
What already exists, verified
The inbound half is real code, not aspiration: auth/policy.go carries TrustedIssuer configuration; JWKS discovery, OIDC verification, token exchange (exchange_oauth.go, exchange_cloud.go), federation, a broker that mints assertions, tenancy and namespace grammar are all in pkg/flowstate/v1/auth/. Outbound, the http task's credential: input does JIT federation inside the activity, so a workload names a credential and never holds one. This record is about finishing the picture, not starting it.
The four directions
1. Inbound machine identity: the GitHub Actions bridge (slice 1 candidate, mostly configuration). GHA issues OIDC tokens (token.actions.githubusercontent.com) with repo, ref, and workflow claims. A TrustedIssuer entry for it should make a CI job an attested Flowstate caller: runs started from CI carry the repo identity, and every policy surface (secrets, task shape, egress, signals) can bind on it. This is the not-a-CI-competitor posture made concrete: Flowstate inside GHA with real identity, GHA driven from Flowstate via the github plugin, or either alone. Slice: verify the claim mapping end to end, then an example plus a docs page. If a gap exists (claim shapes, audience validation), it lands in #243's ledger.
2. Outbound delegated authority: three-legged OAuth as a durable wait. The insight that is Flowstate-native rather than borrowed: a consent flow is a park-and-resume. A run that needs to act on behalf of a human starts the authorization-code flow (PKCE, per OAuth 2.1), parks on the wait machinery that already survives days, and resumes when the callback arrives as an attested signal. No polling process, no held state, no credential in history: the resulting grant lives in the secrets substrate as a reference, refreshed inside activities. Design questions to settle: where the callback lands (the server's webhook surface, direction 4), how the grant is scoped to the run vs the tenant, and what the Flowfile spelling is (likely a task or plugin capability, not new grammar).
3. On-behalf-of chains: token exchange as the composition rule. RFC 8693 exchange already has a seam in auth/. The emerging patterns the owner names (XAA, identity-assertion authorization grants) are this shape: an upstream identity is exchanged, with audience narrowing, for a downstream credential, and the chain is auditable. For Flowstate: a run's identity exchanged per task, per audience, so a workflow calling three services holds three narrow tokens minted just in time, never one broad one. This is #173's ladder with a standards-track mechanism, and it is what the MCP surface needs when agents call Flowstate on behalf of users: the MCP spec's auth model is OAuth 2.1, so flow mcp serving HTTP should slot into it rather than invent parallel auth.
4. Webhooks, both directions, as attested signals. Inbound: a webhook endpoint that verifies provider signatures (GitHub HMAC, Stripe style) and delivers the event as a signal whose sender identity names the provider, so signals: policy and the #206 machinery govern machine events exactly as they govern human approvals. Outbound: a first-class delivery task with signing, retries under the run's policy, and the receipt as a step output. #159 owns the trigger grammar; this record owns the identity semantics: an unverifiable webhook is an unattested sender and is refused, the same fail-closed rule everything else follows.
What must stay true
The house rules extend, not bend: no credential in history (grants are references, invariant 7 containment tests on every new shape); deny by default (an unverified webhook, an unexchangeable token, an expired grant all refuse); both drivers agree (local rehearsal of a consent flow stubs the provider through flow test's machinery rather than lying); the schema is the contract (grant metadata, webhook receipts, exchange requests are proto messages); and nothing here is lock-in (every mechanism is standards-track: OIDC, OAuth 2.1, RFC 8693, JWKS, so a deployment can front Flowstate with its own IdP and walk away whole).
Sequencing
- GHA bridge verification plus example (cheap, high signal, may be pure configuration).
- Webhook inbound with signature verification as attested signals (builds on #159 and #194's sender machinery).
- Token exchange per task audience (the
credential:seam widened along #173). - Durable consent (the three-legged flow), which needs 2's callback surface and 3's grant storage.
- MCP-surface OAuth 2.1 alignment, tracked with #108.
Explicitly not this record: a bundled IdP (Flowstate verifies and exchanges, it does not become an identity provider beyond the workload-identity broker it already has), and any UI. The hub thesis stands on standards and the plugin surface, not on owning the login page.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with pkg/flowstate/v1/auth/, especially auth/policy.go, exchange_oauth.go, and exchange_cloud.go, then review #243 and the proposed sequencing. A feasible first slice is end-to-end GitHub Actions claim mapping, an example, and a documentation page; completion should verify the mapping and identify any remaining gaps in #243's ledger.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github, github-actions, go
- Domain
- api, authentication, backend, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100