steev/credbridge.sh
Svrnty 2491d48151 feat(steev): Wave 8 PAUSE-walk — apply Q4-Q10 + bte leak fix + proton-tools SKILL.md
Q4: confirm personal-scope discriminators (chat_facing, delegates_to=[ceo-planb], sovereign_only=false)
Q5: drop google-workspace cred — builtin manages own OAuth via Hermes hub (not credctl vault)
Q6: split proton-bridge-imap → proton-bridge-imap-user + proton-bridge-imap-pass (vault exact-match)
Q7: rename perplexity-api → perplexity (vault exact-match)
Q8: add 3 proton vault entries (account-email, account-password, mailbox-password)
Q9: install.sh F6 — MCP allowlist materialization; wires 3 proton MCPs, removes bte (hard-rule leak)
Q10: macOS-only externals annotated os_constraint:darwin; install.sh F7 emits INFO on non-Darwin

credbridge.sh: drop google-workspace case, rewrite proton-bridge to use 2 vault entries, rename perplexity case
Disclosure §7 rewritten with 6 credentials matching vault exact-name policy (DISCLOSURE-SCHEMA §4.5)
Disclosure §12 PAUSE table marked all 8 rows RESOLVED (rows 1-7 Wave 8, row 8 Wave 7)

Untracked skills/proton-tools/SKILL.md (90 lines, declared in manifest since Wave 4) — committed for clone-ability

Verified:
  hermes -p steev skills list → 6 enabled (matches disclosure.skills declaration)
  hermes -p steev mcp list → 3 entries (proton-calendar, proton-email, proton-contacts); bte removed
  F7 on Linux host correctly suppresses macOS-only externals

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 18:13:40 -04:00

82 lines
3.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# credbridge.sh — resolve credctl credentials into env vars for steev's
# personal-flow tools, then exec the CLI. Secrets NEVER echoed, logged, or
# written to disk.
#
# Usage: credbridge.sh <tool> [args...]
# tools: proton-bridge | perplexity
#
# Per PROFILE-DISTRIBUTION-PROTOCOL §3 (shared core, "credbridge" row) and §6
# (Conventions → Secrets), every profile distribution exposes credentials via
# this verb chain: credctl set → credenv → exec, with secrets per-call only.
#
# This is the personal-assistant variant of the credbridge pattern. Steev's
# cred surface is narrow by design:
#
# - proton-bridge: IMAP/SMTP user + password for the local Proton Bridge
# T6 sidecar — gives Steev access to JP's Proton mail
# via himalaya (cleartext on 127.0.0.1 only)
# - perplexity: Perplexity API key for WebSearch toolset (lightweight
# — most Steev work uses the perplexity MCP instead)
#
# Wave 8 (2026-05-24): google-workspace case REMOVED — Hermes builtin
# google-workspace skill manages its own OAuth flow via the Hermes hub, not
# the credctl vault. Vault contains no google-workspace-* entries.
#
# Plan B marketing platforms (WooCommerce, Mailchimp, Meta, GA4, etc.) are OUT
# OF SCOPE here — that's cmo-planb's credbridge. Steev MUST NEVER resolve a
# marketing platform credential. The CLAUDE.md "no access to Plan B marketing
# platform credentials" rule is enforced by omission from this case statement.
#
# Design notes (same as cmo/credbridge.sh — shared core):
# - credctl values read into local vars, exported straight to the child env
# - No `echo $secret`. set +x stays off.
set -euo pipefail
# Paths env-overridable for portability; defaults match the JP install.
CREDCTL="${CREDCTL:-/home/svrnty/workspaces/cortex/L6-svrnty.core-credentials/credctl}"
STEEV_LIB="${STEEV_LIB:-/home/svrnty/.hermes/steev}"
die() { printf '{"error":"%s"}\n' "$1" >&2; exit 1; }
[ $# -ge 1 ] || die "usage: credbridge.sh <proton-bridge|perplexity> [args...]"
TOOL="$1"; shift
[ -x "$CREDCTL" ] || die "credctl not found/executable at $CREDCTL"
# cred_raw <name> — print unmasked credential value to stdout. Caller captures
# into a var; value never displayed. Strips the "Value:" header from credctl.
cred_raw() {
"$CREDCTL" get "$1" --unmask 2>/dev/null \
| sed -n '/^Value:/,$p' | sed '1s/^Value:[[:space:]]*//'
}
case "$TOOL" in
proton-bridge)
# Steev reads JP's Proton inbox via the local Proton Bridge IMAP daemon
# (T6 sidecar — see PROFILE-DISTRIBUTION-PROTOCOL §4.T6). credctl stores
# user + password as separate vault entries (Wave 8 aligned to vault).
PB_USER="$(cred_raw proton-bridge-imap-user)"
[ -n "$PB_USER" ] || die "credctl: proton-bridge-imap-user not set"
PB_PASS="$(cred_raw proton-bridge-imap-pass)"
[ -n "$PB_PASS" ] || die "credctl: proton-bridge-imap-pass not set"
export PROTON_BRIDGE_IMAP_USER="$PB_USER"
export PROTON_BRIDGE_IMAP_PASSWORD="$PB_PASS"
exec "$@"
;;
perplexity)
# Lightweight WebSearch path. Most Steev research goes through the
# perplexity MCP server (which holds its own key); this credbridge entry
# exists for scripts that need a raw key (rare). Wave 8 renamed
# vault entry `perplexity-api` → `perplexity`.
PPL_KEY="$(cred_raw perplexity)"
[ -n "$PPL_KEY" ] || die "credctl: perplexity not set"
export PERPLEXITY_API_KEY="$PPL_KEY"
exec "$@"
;;
*)
die "unknown tool: $TOOL (allowed: proton-bridge|perplexity)"
;;
esac