picatz / picatz/flowstate

http task's headers: is map<string,string> — stringly-typed and can't hold a resolvable value

Open
#122 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

dsl enhancement
Dominant language
Go
Stars
9
Forks
0
Avg merge
3h 3m
Merged PRs (30d)
509

Description

Came up reviewing PR #118 (README's secrets section): headers: refuses a secret reference because it's typed map<string, string> in the schema, which structurally cannot hold anything but a literal — no expression, no secret ref. That's why bearer:/credential: exist as a separate, special-cased escape hatch instead of headers just being able to carry a resolvable value like every other task input.

Two separate problems, not one:

  1. Can't carry anything but a literal. map<string,string> means a header value is always a plain string in the spec/history. Any header that should be resolved at execution time (a custom X-Api-Key: header, say) has no path — only Authorization gets one, via bearer:.
  2. Doesn't model HTTP headers correctly even ignoring secrets. HTTP headers are key→multiple values (RFC 7230) — repeated Set-Cookie, multiple Accept/Vary entries. A map<string,string> can't represent that at all; today's headers can only ever send one value per name.

Direction (not decided, needs a call before implementing)

repeated Header{name: string, value: Value} (or similar), where Value is the same literal/expression/secret-ref oneof every other task input uses. This is a proto schema change — buf generate, flow fix rewriter support for migrating existing headers: blocks, and validator updates — not a small patch.

The tradeoff to resolve first: making headers structured lets any header name carry a secret ref resolved inside the activity, not just Authorization via bearer:. That's more flexible, but it widens the audited, scrub-discipline surface from one narrow field to every header — CLAUDE.md's "secrets never enter workflow history" containment work would need to apply per-header-value rather than to the one field it currently concentrates on. Worth deciding deliberately rather than as a side effect of the schema change.

Related: the four-way refusal (headers:, query:, JSON/raw body:, expressions) documented in PR #118's README fix — this issue would let one of those four stop being refused, and it should be intentional about why the other three stay refused if it does.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the README secrets section from PR #118 and CLAUDE.md to understand the current containment rules for secret values. Then inspect the task schema, validator, and flow fix migration path mentioned in the issue, along with the buf generate workflow. Before implementation, decide whether per-header resolvable values are acceptable and document what migration and validation behavior would count as done.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
api, backend-api-design, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.