Skip to content

feat(tunnel): N4 — cloudflared wrapper + ingress + secret refusal; CI skips docs - #23

Merged
gustavobertoi merged 1 commit into
mainfrom
nightly/N4
Jun 29, 2026
Merged

feat(tunnel): N4 — cloudflared wrapper + ingress + secret refusal; CI skips docs#23
gustavobertoi merged 1 commit into
mainfrom
nightly/N4

Conversation

@gustavobertoi

Copy link
Copy Markdown
Contributor

Chunk N4 (M5)

internal/tunnel manages the optional, default-down, account-gated public tunnel (spec 05), behind an injectable Runner (fully unit-testable without cloudflared or a Cloudflare account):

  • Available / Login / Create(name) / RouteDNS(name, host) / Run(config). RouteDNS refuses a wildcard with the manual-CNAME remediation (cloudflared rejects *).
  • IngressConfig renders a deterministic cloudflared config.yml mapping every public hostname → the shared Caddy upstream (public reuses local routing, no drift) + the required 404 catch-all last.
  • SecretBearing returns the non-local secret:// refs in a service's env so a tunnel refuses to expose a service carrying remote secrets without override (nil/unknown classifier fails safe).
  • CLI tunnel login|create|route replaces the stub (account verbs); running the tunnel container with routes-derived ingress is the saga's job (N5).

CI efficiency

Adds paths-ignore for **/*.md/docs//LICENSE/NOTICE so docs-only PRs skip the consolidated lane (the e2e step made every PR ~4.5 min).

Tests

Fake runner: available, verbs-need-binary, create+route call-through, wildcard refusal, empty-name error, deterministic ingress + 404-last, SecretBearing local-vs-non-local (+ fail-safe nil). CLI registration.

Gate

make ci green (race).

🤖 Generated with Claude Code

… skips docs

internal/tunnel manages the optional, default-down, account-gated public tunnel
(spec 05), behind an injectable Runner so it is fully unit-testable without the
binary or a Cloudflare account:

- Available / Login / Create(name) / RouteDNS(name, host) / Run(config). RouteDNS
  refuses a wildcard with the manual-CNAME remediation (cloudflared rejects `*`).
- IngressConfig renders a deterministic cloudflared config.yml whose ingress maps
  every public hostname → the shared Caddy upstream (public reuses local routing,
  no drift) with the required 404 catch-all last.
- SecretBearing returns the NON-local secret:// refs in a service's env so a
  tunnel refuses to expose a service carrying remote secrets without override
  (a nil/unknown classifier fails safe → treats all as non-local).
- CLI `tunnel login|create|route` replaces the stub (account verbs); running the
  tunnel container with routes-derived ingress is wired into the saga (N5).

CI: add `paths-ignore` for `**/*.md`/docs/LICENSE/NOTICE so docs-only PRs skip
the now-heavier consolidated lane (the e2e step made every PR ~4.5 min).

Unit-tested (fake runner): available, verbs-need-binary, create+route call-through,
wildcard refusal, empty-name error, deterministic ingress rendering + 404 last,
SecretBearing local-vs-nonlocal (+ fail-safe nil). CLI registration test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gustavobertoi
gustavobertoi merged commit 91f206f into main Jun 29, 2026
2 checks passed
@gustavobertoi
gustavobertoi deleted the nightly/N4 branch June 29, 2026 15:08
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