Implements SECRETS-WP-0002 end to end as a uv-managed Python package: - catalog: non-secret lane registry + strict validator (build/test/prod) - stage roles + OpenBao ACL policies; guards refuse wildcards, sys/, identity/, admin names, and cross-stage paths before any backend call - plan/apply: dry-run-first, idempotent policy + approle apply, decision-gated - decisions: State Hub lookup with local-fixture fallback; non-secret evidence to JSONL + hub progress, scrubbed of any value - provision/verify: mode-0600 file import + generated test values; positive/ negative checks that never print the value - exec delivery: `exec --catalog ... -- npm publish` injects the token via a temp .npmrc for the child only, cleaned up on exit/failure/interrupt - ops-warden routing contract + hardening backlog docs - 34 tests incl. live OpenBao integration; scripts/demo-e2e.sh runs the full chain against a throwaway bao dev server Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
91 lines
3.2 KiB
Bash
Executable file
91 lines
3.2 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# End-to-end MVP demo for the whynot-design npm publish lane.
|
|
#
|
|
# Boots a throwaway OpenBao dev server, then drives the full secrets-engine chain:
|
|
# plan (dry-run) -> apply -> provision (from mode-0600 file) -> verify +/-
|
|
# -> exec (npm-config injection into a child) -> route -> revoke.
|
|
#
|
|
# Nothing here is production. The dev server is in-memory and discarded on exit.
|
|
# The "token" is a throwaway local string written to a mode-0600 temp file.
|
|
set -euo pipefail
|
|
|
|
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
cd "$REPO"
|
|
|
|
# shellcheck disable=SC1091
|
|
source .venv/bin/activate
|
|
|
|
BAO_BIN="$(command -v bao)"
|
|
WORK="$(mktemp -d)"
|
|
export BAO_ADDR="http://127.0.0.1:8270"
|
|
export BAO_TOKEN="se-demo-root"
|
|
# Keep secret material OUTSIDE the repo worktree (engine enforces this).
|
|
TOKENFILE="$WORK/whynot.token"
|
|
|
|
cleanup() {
|
|
set +e
|
|
[[ -n "${BAO_PID:-}" ]] && kill "$BAO_PID" 2>/dev/null
|
|
rm -rf "$WORK"
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
echo "### 0. boot throwaway OpenBao dev server (in-memory)"
|
|
"$BAO_BIN" server -dev -dev-root-token-id="$BAO_TOKEN" \
|
|
-dev-listen-address="127.0.0.1:8270" >"$WORK/bao.log" 2>&1 &
|
|
BAO_PID=$!
|
|
for _ in $(seq 1 30); do
|
|
"$BAO_BIN" status -address="$BAO_ADDR" >/dev/null 2>&1 && break
|
|
sleep 0.2
|
|
done
|
|
|
|
echo
|
|
echo "### 1. plan (dry-run, no mutation)"
|
|
secrets-engine plan whynot-design-npm-publish --stage prod | sed 's/^/ /'
|
|
|
|
echo
|
|
echo "### 2. apply approved metadata (policy + approle) to OpenBao"
|
|
secrets-engine apply whynot-design-npm-publish --stage prod | sed 's/^/ /'
|
|
|
|
echo
|
|
echo "### 2b. apply is idempotent (re-run shows 'unchanged')"
|
|
secrets-engine apply whynot-design-npm-publish --stage prod | sed 's/^/ /'
|
|
|
|
echo
|
|
echo "### 3. provision the token from a mode-0600 file outside the repo"
|
|
printf 'npm_demoTOKENvalue1234567890abcd' > "$TOKENFILE"
|
|
chmod 600 "$TOKENFILE"
|
|
secrets-engine provision whynot-design-npm-publish --stage prod \
|
|
--field npm_token --from-file "$TOKENFILE" | sed 's/^/ /'
|
|
|
|
echo
|
|
echo "### 4. verify positive (approved consumer can read) + negative (others denied)"
|
|
secrets-engine verify whynot-design-npm-publish --field npm_token --positive --negative | sed 's/^/ /'
|
|
|
|
echo
|
|
echo "### 5. exec-time delivery: child sees the token via a temp npmrc; parent never does"
|
|
cat > "$WORK/fake-npm" <<'EOF'
|
|
#!/usr/bin/env bash
|
|
# Stand-in for 'npm publish' — proves the child can resolve the token and the
|
|
# parent shell cannot. Prints only whether the token is reachable, never the value.
|
|
if [[ -n "${NPM_CONFIG_USERCONFIG:-}" ]] && grep -q '_authToken' "$NPM_CONFIG_USERCONFIG"; then
|
|
echo " [child] npm userconfig present; _authToken resolvable: yes"
|
|
else
|
|
echo " [child] NO token available"; exit 1
|
|
fi
|
|
echo " [child] would run: npm $*"
|
|
EOF
|
|
chmod +x "$WORK/fake-npm"
|
|
secrets-engine exec --catalog whynot-design-npm-publish -- "$WORK/fake-npm" publish
|
|
|
|
echo " [parent] SE_NPM_TOKEN in parent shell: '${SE_NPM_TOKEN:-<unset>}'"
|
|
|
|
echo
|
|
echo "### 6. ops-warden routing pointer (ready=true expected)"
|
|
secrets-engine route whynot-design-npm-publish --json | sed 's/^/ /'
|
|
|
|
echo
|
|
echo "### 7. revoke (deactivate the lane)"
|
|
secrets-engine revoke whynot-design-npm-publish | sed 's/^/ /'
|
|
|
|
echo
|
|
echo "### DONE — full chain exercised against a live OpenBao."
|