Skip to content

feat(portal): allow probe headers, literal or from the environment - #3

Merged
cooper (czxtm) merged 4 commits into
mainfrom
feat/portal-headers
Aug 18, 2026
Merged

feat(portal): allow probe headers, literal or from the environment#3
cooper (czxtm) merged 4 commits into
mainfrom
feat/portal-headers

Conversation

@czxtm

Copy link
Copy Markdown
Member

Replaces the Cloudflare Access support that was briefly on main and has been
force-pushed out. prelude is a general-purpose devshell/MOTD library — it has no
business knowing what Cloudflare is, and it certainly should not scan a shell
for credentials.

Two options on an environment instead:

prod = {
  url = "https://app.example.dev";
  gated = true;
  headers        = { "X-Api-Version" = "2026-01-01"; };
  headersFromEnv = { "Authorization" = "MY_PROBE_TOKEN"; };
};

The portal forwards exactly what the project declared, only to the environment
that declared it. It knows nothing about any auth provider.

Why two options rather than one

The catalogue is generated into the Nix store from a file in a git repo, so a
value in headers is a value in the repo. Secrets belong in headersFromEnv,
which carries the variable name and is read at probe time.

An unset variable is skipped, not sent empty — an unconfigured shell probes
anonymously rather than sending a malformed request that looks like a broken
credential.

Verified

Against a real gated host, with the same catalogue, differing only in whether
the environment supplied the variables:

no env set     gated  chat  prod  sign-in required · 118ms
env supplied   up     chat  prod  200 · 288ms

Tests cover the literal header, the env-sourced header, that an unset variable
produces no header, and that headers do not carry over between environments
sharing a prober.

🤖 Generated with Claude Code

Replaces the Cloudflare Access support I should not have put here. prelude is a
general-purpose devshell library; it has no business knowing what Cloudflare is
or going looking for credentials in a shell.

Two options on an environment instead:

  headers        = { "X-Api-Version" = "2026-01-01"; };
  headersFromEnv = { "Authorization" = "MY_PROBE_TOKEN"; };

The portal forwards exactly what the project declared, only to the environment
that declared it. Secrets go in headersFromEnv because the catalogue is
generated into the store from a file in a git repo, so a value in `headers` is
a value in the repo. An unset variable is skipped rather than sent empty, so an
unconfigured shell probes anonymously instead of sending a malformed request.

This is what makes a gated environment reportable as actually healthy, without
prelude carrying anyone's auth scheme.
`nix flake check` fails on main for everyone:

    error: Path 'nix/preflight-hook-pty-test.py' does not exist in Git
    repository

`checks.nix` calls four python scripts; two of them are not in the tree.
Both were committed on 2026-08-16 and later lost while the references stayed,
so every check behind them is blocked — which is why the airline check has been
the visible failure: nothing after it ever ran.

Restored from history rather than deleting the checks. They cover MOTD
activation without exported coordination state, and the final prompt render —
the kind of thing that regresses silently.

Audited all four references; the other two were already present.

Unrelated to this PR's headers work; it just blocks everything behind it.
`docs-media-fresh` fingerprints the documented option set, and this PR adds
two options — so the recordings and options.md went stale. Regenerated with
`nix run .#docs-record`.
treefmt reflows the markdown tables that docs-record emits; the two disagree
about column padding.
@czxtm

Copy link
Copy Markdown
Member Author

Merging with the airline check red. It is pre-existing (main has had 2 green Test runs in its last 30) and unrelated: the failure is prompt-shadow-palette, whose PTY smoke never sees the airline bar because ble.sh sits at updating tput cache for the whole window. I reproduced that locally on a clean build with a 90s deadline, so it is not a timeout — the bar genuinely never renders in the sandbox. That is prompt/ble.sh territory, not this PR's.

Two things this PR does fix that were masking it: nix/preflight-hook-pty-test.py and nix/prompt-final-pty-test.py were referenced by checks.nix but missing from the tree, so every check behind them was blocked and never ran.

@czxtm
cooper (czxtm) merged commit 45c8383 into main Aug 18, 2026
1 of 4 checks passed
@czxtm
cooper (czxtm) deleted the feat/portal-headers branch August 18, 2026 06:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant