Skip to content

Commit bf1fad6

Browse files
feat: show protocol and access policy in zt list / zt status
Neither was visible without running `zt status` per tunnel one at a time (protocol) or not at all (access policy) — for a security tool, whether a given tunnel is public or gated behind Zero Trust is exactly the kind of thing that should be visible at a glance across all tunnels, not just discoverable per-tunnel. - cmd/zt/list.go: new accessLabel() ("public" in yellow, or "ZT (N email(s))" in green); PROTOCOL and ACCESS columns added to `zt list`'s table (reusing the existing protocolLabel() helper) and as a new "Access:" line in `zt status` - README.md: updated the zt list/zt status example output to match
1 parent 1978ec3 commit bf1fad6

2 files changed

Lines changed: 29 additions & 5 deletions

File tree

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -309,9 +309,9 @@ zt list # or: zt ls
309309
```
310310

311311
```
312-
NAME URL PORT STATUS MANAGED BY
313-
portainer https://portainer.example.com 9000 running systemd
314-
grafana https://grafana.example.com 3000 stopped pid 84291
312+
NAME URL PORT PROTOCOL ACCESS STATUS MANAGED BY
313+
portainer https://portainer.example.com 9000 auto (quic) ZT (1 email) running systemd
314+
grafana https://grafana.example.com 3000 http2 (TCP) public stopped pid 84291
315315
```
316316

317317
### Tunnel details
@@ -326,8 +326,9 @@ zt status portainer
326326
Port: 9000
327327
Tunnel ID: 07fc193d-d05e-48eb-bb00-22be71823b14
328328
Managed by: systemd
329-
Status: running
330329
Protocol: http2 (TCP)
330+
Access: ZT (1 email)
331+
Status: running
331332
Created: 2026-05-27 00:01:08
332333
Log: /root/.zt/tunnels/portainer/cloudflared.log
333334
```

cmd/zt/list.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ func runList(cmd *cobra.Command, args []string) error {
237237
})
238238

239239
table := tablewriter.NewWriter(os.Stdout)
240-
table.SetHeader([]string{"NAME", "URL", "PORT", "STATUS", "MANAGED BY"})
240+
table.SetHeader([]string{"NAME", "URL", "PORT", "PROTOCOL", "ACCESS", "STATUS", "MANAGED BY"})
241241
table.SetBorder(false)
242242
table.SetColumnSeparator(" ")
243243
table.SetHeaderLine(false)
@@ -248,10 +248,13 @@ func runList(cmd *cobra.Command, args []string) error {
248248

249249
for _, t := range tunnels {
250250
status, managedBy := tunnelStatus(t)
251+
path, _ := logPath(t.Name)
251252
table.Append([]string{
252253
t.Name,
253254
"https://" + t.Hostname,
254255
fmt.Sprintf("%d", t.Port),
256+
protocolLabel(t.Protocol, path),
257+
accessLabel(t),
255258
status,
256259
managedBy,
257260
})
@@ -288,6 +291,7 @@ func runStatus(cmd *cobra.Command, args []string) error {
288291
fmt.Printf(" Tunnel ID: %s\n", t.TunnelID)
289292
fmt.Printf(" Managed by: %s\n", managedBy)
290293
fmt.Printf(" Protocol: %s\n", protocolLabel(t.Protocol, path))
294+
fmt.Printf(" Access: %s\n", accessLabel(t))
291295
fmt.Printf(" Status: %s\n", statusStr)
292296
fmt.Printf(" Created: %s\n", t.CreatedAt.Format("2006-01-02 15:04:05"))
293297
fmt.Printf(" Log: %s\n", path)
@@ -299,6 +303,25 @@ func runStatus(cmd *cobra.Command, args []string) error {
299303
return nil
300304
}
301305

306+
// accessLabel summarizes a tunnel's access policy for `zt list`/`zt status`:
307+
// "public" (--public, no Access app) or "ZT (N email)" (Access app with an
308+
// allow policy). See the P0 fix requiring --allow or --public on zt up —
309+
// there's no third "bypass" state anymore.
310+
func accessLabel(t *state.Tunnel) string {
311+
yellow := color.New(color.FgYellow).SprintFunc()
312+
green := color.New(color.FgGreen).SprintFunc()
313+
314+
if t.Public {
315+
return yellow("public")
316+
}
317+
n := len(t.AllowEmails)
318+
noun := "email"
319+
if n != 1 {
320+
noun = "emails"
321+
}
322+
return green(fmt.Sprintf("ZT (%d %s)", n, noun))
323+
}
324+
302325
func protocolLabel(p state.Protocol, logPath string) string {
303326
switch p {
304327
case state.ProtocolHTTP2:

0 commit comments

Comments
 (0)