@dbx-tools/cli-tunnel 0.6.86 → 0.6.87

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +145 -1
  2. package/package.json +7 -7
package/README.md CHANGED
@@ -1 +1,145 @@
1
- # replace this
1
+ # @dbx-tools/cli-tunnel
2
+
3
+ Wrap any command in a public [portr](https://github.com/amalshaji/portr) tunnel
4
+ fronted by an email one-time-code gate.
5
+
6
+ Run `dbx tunnel -- <command>` when a local or self-hosted process needs a public
7
+ URL that only approved email addresses can reach. The wrapper claims the public
8
+ port, starts your command on a private loopback port, and reverse-proxies between
9
+ them so the gate sits in front of traffic the command itself never has to know
10
+ about.
11
+
12
+ Key features:
13
+
14
+ - Public portr tunnel + email-OTP gate around a command the wrapper does not
15
+ have to modify, import, or even be written in the same language as.
16
+ - A reverse proxy that answers the login routes itself and forwards only
17
+ verified traffic to the wrapped process.
18
+ - Flag → environment → `databricks.yml` resolution for every gate and portr
19
+ setting, delegated to [`@dbx-tools/tunnel`](../../node/tunnel) so the CLI
20
+ cannot drift from the in-process plugin.
21
+ - `status` to print exactly what would happen without starting anything.
22
+ - Two-way process supervision: a crashed child takes the tunnel down instead of
23
+ leaving portr serving a dead port.
24
+ - Lazy loading, so `--insecure`, `status`, and `install` never load AppKit, the
25
+ Databricks SDK, or the SMTP stack.
26
+
27
+ ## Why Not The AppKit Plugin?
28
+
29
+ Use the in-process path when you can. An app that boots through
30
+ [`@dbx-tools/appkit`](../../node/appkit)'s `createApp` should register
31
+ `tunnelInterceptor()` plus the `authGate` plugin from
32
+ [`@dbx-tools/tunnel`](../../node/tunnel): one process, no proxy hop, no
33
+ duplicated header handling.
34
+
35
+ Use this wrapper for the case that path cannot cover:
36
+
37
+ - a project that does not call `appkit.createApp`, so there is no plugin
38
+ lifecycle to register a gate in;
39
+ - a process that is not a Node/AppKit server at all - a Python service, a static
40
+ file server, a third-party binary;
41
+ - a command you want gated without editing its source.
42
+
43
+ The gating DECISION is shared either way. The proxy calls `@dbx-tools/tunnel`'s
44
+ `gate.gateRequest` - the same function the Express middleware uses - so which
45
+ requests are gated and which headers are stripped has exactly one
46
+ implementation.
47
+
48
+ ## Run A Tunnel
49
+
50
+ ```sh
51
+ dbx tunnel --allow databricks.com -- bun src/server.ts
52
+ ```
53
+
54
+ This package ships no bin. It contributes the `tunnel` command group to the
55
+ single `dbx` CLI in [`@dbx-tools/cli`](../dbx-tools), which is what you install:
56
+
57
+ ```sh
58
+ npm install --global @dbx-tools/cli
59
+ dbx tunnel --help
60
+ ```
61
+
62
+ `dbx` imports this package lazily, so `dbx dev` pays for none of it.
63
+
64
+ The command after `--` is spawned with `DATABRICKS_APP_PORT`, `PORT`, and
65
+ `HOST=127.0.0.1` pointing at a private port, so a server that honors those
66
+ variables needs no changes. `run` is both the default action and a named
67
+ subcommand, so `dbx tunnel -- cmd` and `dbx tunnel run -- cmd` are equivalent.
68
+
69
+ ## Check What Would Happen
70
+
71
+ ```sh
72
+ dbx tunnel status --allow databricks.com
73
+ ```
74
+
75
+ The most common failure is a tunnel that silently does nothing because no portr
76
+ token or public domain resolved. `status` prints the fully resolved ports, gate
77
+ config, and portr config as JSON without starting a process.
78
+
79
+ ```sh
80
+ dbx tunnel install
81
+ ```
82
+
83
+ `install` downloads the portr binary and exits, so a first run does not pay for
84
+ the download.
85
+
86
+ ## Commands And Flags
87
+
88
+ ```
89
+ dbx tunnel [options] -- <command...> # wrap a command (default)
90
+ dbx tunnel run [options] -- <command...>
91
+ dbx tunnel status [options]
92
+ dbx tunnel install
93
+ ```
94
+
95
+ Every flag below is accepted on the root command and on `run` / `status`.
96
+ Omitted values fall back to the environment, a `.env` file, then
97
+ `databricks.yml`, through [`@dbx-tools/core`](../../node/core)'s `config`.
98
+
99
+ | Flag | Meaning |
100
+ | ----------------------------- | ---------------------------------------------------------- |
101
+ | `--public-domain <host>` | portr public domain (`<subdomain>.<server>`) |
102
+ | `--subdomain <name>` | portr subdomain, else derived from the public domain |
103
+ | `--port <port>` | public port the wrapper listens on (`DATABRICKS_APP_PORT`) |
104
+ | `--app-port <port>` | private port the wrapped app binds, else a free one |
105
+ | `--allow <patterns...>` | email allow-list (domain, glob, or `/regex/`) |
106
+ | `--subject <text>` | verification email subject |
107
+ | `--brand-name <name>` | verification email brand name |
108
+ | `--message <text>` | verification email message |
109
+ | `--session-ttl <seconds>` | session lifetime |
110
+ | `--code-ttl <seconds>` | one-time-code lifetime |
111
+ | `--session-cutoff <when>` | invalidate every session issued before this |
112
+ | `--forward-headers <pats...>` | extra `x-` headers tunnel traffic may forward |
113
+ | `--insecure` | run open, with no gate |
114
+
115
+ Leave `--subject` and `--brand-name` alone unless you have a reason: the
116
+ defaults are the conventional one-time-code wording that iOS, Gmail, Outlook,
117
+ and Android detect for autofill, and a novel subject breaks that.
118
+
119
+ `--insecure` serves the tunnel with no gate at all and logs a warning. It is for
120
+ local debugging, not for anything reachable.
121
+
122
+ ## How A Request Flows
123
+
124
+ 1. The wrapper binds the PUBLIC port - the one portr and the Databricks Apps
125
+ runtime route to - and spawns the command on a private loopback port.
126
+ 2. A login route (`/auth/*`) is answered by the proxy itself, using the gate
127
+ handlers from a server-less AppKit app that supplies the code store, signing
128
+ key, and email transport.
129
+ 3. Anything else goes through `gate.gateRequest`. A verified session is proxied
130
+ to the child with caller-supplied `x-` headers stripped; an unverified
131
+ request gets the login page or a `401`.
132
+ 4. portr publishes the public port once a token and domain resolve. Without
133
+ them the wrapper still serves locally and says so.
134
+
135
+ ## Modules
136
+
137
+ - `cli` - the `dbx tunnel` commander program: `buildProgram(name?)`, which
138
+ `@dbx-tools/cli` mounts.
139
+ - `options` - `resolveTunnelOptions()`, flag → config → default resolution.
140
+ - `proxy` - `startProxy()`, the gate-aware reverse proxy.
141
+ - `app` - `startGateApp()`, the server-less AppKit app behind the gate.
142
+
143
+ Gate behavior, portr lifecycle, and header policy live in
144
+ [`@dbx-tools/tunnel`](../../node/tunnel); email delivery in
145
+ [`@dbx-tools/email`](../../node/email).
package/package.json CHANGED
@@ -23,12 +23,12 @@
23
23
  "typescript": "^5.9.3"
24
24
  },
25
25
  "dependencies": {
26
- "@dbx-tools/appkit": "0.6.86",
27
- "@dbx-tools/core": "0.6.86",
28
- "@dbx-tools/email": "0.6.86",
29
- "@dbx-tools/shared-core": "0.6.86",
30
- "@dbx-tools/shared-email": "0.6.86",
31
- "@dbx-tools/tunnel": "0.6.86",
26
+ "@dbx-tools/appkit": "0.6.87",
27
+ "@dbx-tools/core": "0.6.87",
28
+ "@dbx-tools/email": "0.6.87",
29
+ "@dbx-tools/shared-core": "0.6.87",
30
+ "@dbx-tools/shared-email": "0.6.87",
31
+ "@dbx-tools/tunnel": "0.6.87",
32
32
  "commander": "^15.0.0",
33
33
  "http-proxy-3": "^1.23.1"
34
34
  },
@@ -62,7 +62,7 @@
62
62
  "./package.json": "./package.json"
63
63
  }
64
64
  },
65
- "version": "0.6.86",
65
+ "version": "0.6.87",
66
66
  "types": "./lib/index.d.ts",
67
67
  "type": "module",
68
68
  "exports": {