@dbx-tools/cli-tunnel 0.6.85 → 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.
- package/README.md +145 -1
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -1 +1,145 @@
|
|
|
1
|
-
#
|
|
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.
|
|
27
|
-
"@dbx-tools/core": "0.6.
|
|
28
|
-
"@dbx-tools/email": "0.6.
|
|
29
|
-
"@dbx-tools/shared-core": "0.6.
|
|
30
|
-
"@dbx-tools/shared-email": "0.6.
|
|
31
|
-
"@dbx-tools/tunnel": "0.6.
|
|
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.
|
|
65
|
+
"version": "0.6.87",
|
|
66
66
|
"types": "./lib/index.d.ts",
|
|
67
67
|
"type": "module",
|
|
68
68
|
"exports": {
|