1 Commits

Author SHA1 Message Date
b886f9d222 Add terminal package with secure ReadPassword helper
Provides echo-suppressed password prompting via golang.org/x/term for
CLI login commands. Added as a platform standard in engineering-standards.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:10:06 -07:00
5 changed files with 41 additions and 0 deletions

View File

@@ -37,6 +37,7 @@ go test ./auth/ -run TestCacheExpiry
| `web` | Session cookies, auth middleware, template rendering for htmx UIs |
| `health` | REST and gRPC health check handlers |
| `archive` | tar.zst snapshots with SQLite-aware backup (VACUUM INTO) |
| `terminal` | Secure terminal input (echo-suppressed password prompts) |
## Import Pattern
@@ -63,6 +64,7 @@ db --> (modernc.org/sqlite)
grpcserver --> auth, config
health --> db
httpserver --> config
terminal --> (golang.org/x/term)
web --> auth, csrf
```

1
go.mod
View File

@@ -18,6 +18,7 @@ require (
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
golang.org/x/net v0.48.0 // indirect
golang.org/x/sys v0.42.0 // indirect
golang.org/x/term v0.41.0 // indirect
golang.org/x/text v0.32.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect
google.golang.org/protobuf v1.36.10 // indirect

2
go.sum
View File

@@ -49,6 +49,8 @@ golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU=
golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A=
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=

22
terminal/terminal.go Normal file
View File

@@ -0,0 +1,22 @@
// Package terminal provides secure terminal input helpers for CLI tools.
package terminal
import (
"fmt"
"os"
"golang.org/x/term"
)
// ReadPassword prints the given prompt to stderr and reads a password
// from the terminal with echo disabled. It prints a newline after the
// input is complete so the cursor advances normally.
func ReadPassword(prompt string) (string, error) {
fmt.Fprint(os.Stderr, prompt)
b, err := term.ReadPassword(int(os.Stdin.Fd())) //nolint:gosec // fd fits in int
fmt.Fprintln(os.Stderr)
if err != nil {
return "", err
}
return string(b), nil
}

14
terminal/terminal_test.go Normal file
View File

@@ -0,0 +1,14 @@
package terminal
import (
"testing"
)
func TestReadPasswordNotATTY(t *testing.T) {
// When stdin is not a terminal (e.g. in CI), ReadPassword should
// return an error rather than hanging or panicking.
_, err := ReadPassword("Password: ")
if err == nil {
t.Fatal("expected error when stdin is not a terminal")
}
}