Add end-to-end smoke and rewrite the README for v0

The smoke boots the fake Secrets Manager in a container and drives the
real binary from the host through a 0600 env file: login, listings, get
by name and uuid, failure paths, and a redaction sweep over every
captured output. README documents the implemented wire protocol, the
library surface keyproxy will call, the verified quickstart, and the
config table.
This commit is contained in:
2026-08-29 00:08:38 -05:00
parent edf056eb9f
commit 9b730afd12
4 changed files with 329 additions and 38 deletions
Executable
+113
View File
@@ -0,0 +1,113 @@
#!/bin/sh
# End-to-end smoke for bitwarden-go: builds the CLI in the Docker builder,
# boots the FAKE Secrets Manager in a container on 127.0.0.1:8600, drives
# the real binary from the host through a 0600 env file, and asserts the
# happy paths plus redaction. No real vault is ever contacted. Only exact
# container IDs / PIDs spawned here are killed.
set -e
cd "$(dirname "$0")/.."
IMAGE="golang@sha256:e8c859f5632dcfde7b32d2012b4351728f6437930887c2f6a91ea242459e5514"
PORT=8600
CID=""
cleanup() {
if [ -n "$CID" ]; then
docker rm -f "$CID" >/dev/null 2>&1 || true
fi
rm -rf .smoke
}
trap cleanup EXIT INT TERM
mkdir -p .smoke
umask 077
echo "--- build CLI (docker builder)"
docker run --rm -v "$PWD:/h" -w /h \
-u "$(id -u):$(id -g)" -e HOME=/tmp -e GOFLAGS=-buildvcs=false \
"$IMAGE" go build -o bin/bitwarden-go ./cmd/bitwarden-go
echo "--- boot fake Secrets Manager (container, port $PORT)"
CID=$(docker run -d --rm \
-v "$PWD:/h" -w /h \
-u "$(id -u):$(id -g)" -e HOME=/tmp -e GOFLAGS=-buildvcs=false \
-p 127.0.0.1:$PORT:8600 \
"$IMAGE" go run ./smoke/fakesm -addr :8600)
# wait for the fake to answer (any HTTP response, even 400, proves it is up)
i=0
until [ -n "$CID" ] && [ "$(docker inspect -f '{{.State.Running}}' "$CID" 2>/dev/null)" = "true" ] && \
printf 'grant_type=client_credentials&client_id=probe&client_secret=probe&scope=api.secrets' \
| python3 -c "
import sys, urllib.request, urllib.error
req = urllib.request.Request('http://127.0.0.1:$PORT/identity/connect/token',
data=sys.stdin.buffer.read(), headers={'Content-Type':'application/x-www-form-urlencoded'})
try:
urllib.request.urlopen(req, timeout=2)
except urllib.error.HTTPError:
sys.exit(0) # got an HTTP answer: server is up
except Exception:
sys.exit(1) # not yet
sys.exit(0)
"; do
i=$((i+1))
if [ "$i" -ge 60 ]; then
echo "smoke: fake server did not come up; logs:" >&2
docker logs "$CID" >&2 || true
exit 1
fi
sleep 1
done
CRED='0.ec2c1d46-6a4b-4751-a310-af9601317f2d.C2IgxjjLF7qSshsbwe8JGcbM075YXw:X8vbvA0bduihIDe/qrzIQQ=='
printf 'BW_SERVER_URL=http://127.0.0.1:%s\nBW_ACCESS_TOKEN=%s\n' "$PORT" "$CRED" > .smoke/env
chmod 600 .smoke/env
export BITWARDENGO_CONFIG="$PWD/.smoke/env"
echo "--- login (credential check; prints summary only)"
./bin/bitwarden-go login | tee .smoke/login.out
grep -q "authenticated: account ec2c1d46-6a4b-4751-a310-af9601317f2d" .smoke/login.out
grep -q "expires" .smoke/login.out
echo "--- projects"
./bin/bitwarden-go projects > .smoke/projects.out
grep -q "ac1d0000-0000-4000-8000-000000000001 harness" .smoke/projects.out
echo "--- secrets list"
./bin/bitwarden-go secrets list > .smoke/secrets.out
grep -q "5ec1e700-0000-4000-8000-00000000000a smoke-redmine-key" .smoke/secrets.out
grep -q "5ec1e700-0000-4000-8000-00000000000b smoke-litellm-key" .smoke/secrets.out
echo "--- get (bare value, no newline)"
V="$(./bin/bitwarden-go get smoke-redmine-key)"
[ "$V" = "smoke-redmine-value-0123456789abcdef" ] || { echo "smoke: wrong value: $V" >&2; exit 1; }
echo "--- get by uuid"
V="$(./bin/bitwarden-go get 5ec1e700-0000-4000-8000-00000000000b)"
[ "$V" = "smoke-litellm-value-fedcba9876543210" ] || { echo "smoke: wrong value: $V" >&2; exit 1; }
echo "--- failure path: missing secret (exit code + redacted stderr)"
if ./bin/bitwarden-go get no-such-secret > .smoke/missing.out 2> .smoke/missing.err; then
echo "smoke: missing secret should fail" >&2; exit 1
fi
grep -q "secret not found" .smoke/missing.err
[ ! -s .smoke/missing.out ] || { echo "smoke: stdout not empty on failure" >&2; exit 1; }
echo "--- failure path: bad credential (exit code)"
printf 'BW_SERVER_URL=http://127.0.0.1:%s\nBW_ACCESS_TOKEN=0.ec2c1d46-6a4b-4751-a310-af9601317f2d.wrong-secret:X8vbvA0bduihIDe/qrzIQQ==\n' "$PORT" > .smoke/bad.env
chmod 600 .smoke/bad.env
if BITWARDENGO_CONFIG="$PWD/.smoke/bad.env" ./bin/bitwarden-go login 2> .smoke/bad.err; then
echo "smoke: bad credential should fail" >&2; exit 1
fi
grep -q "auth failed" .smoke/bad.err
echo "--- redaction: no material in any captured output"
for f in .smoke/login.out .smoke/projects.out .smoke/secrets.out .smoke/missing.err .smoke/bad.err; do
grep -qF 'C2IgxjjLF7qSshsbwe8JGcbM075YXw' "$f" && { echo "smoke: client secret leaked into $f" >&2; exit 1; }
grep -qF 'X8vbvA0bduihIDe/qrzIQQ==' "$f" && { echo "smoke: credential key leaked into $f" >&2; exit 1; }
done
grep -qF 'smoke-litellm-value' .smoke/secrets.out && { echo "smoke: secret value leaked into listing" >&2; exit 1; }
echo "smoke: OK"