Track HiveGrid Cloud planning reference
This commit is contained in:
1 parent
b3d5ea6764
commit
e341c5938a
5784 files changed
+1104929
-3
No files matched your search
+209
@@ -0,0 +1,209 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build the Phase 06 plugin runtime external-audit package.
|
||||
#
|
||||
# Produces a single tar.gz containing:
|
||||
# - the in-scope source code (a curated subset, NOT the whole repo)
|
||||
# - the threat model, attack-surface inventory, internal findings
|
||||
# - the RFP / sign-off template
|
||||
# - the manifest of what's included (with SHA-256 per file)
|
||||
#
|
||||
# Operator workflow:
|
||||
# 1. Run from the repo root: scripts/build-plugin-audit-package.sh
|
||||
# 2. Output lands in artifacts/plugin-audit/<ISO-date>/plugin-audit-<short-sha>.tar.gz
|
||||
# 3. Email the archive to the vendor per the RFP § 8.
|
||||
# 4. Keep the archive AND its checksum locally for forensics — the vendor
|
||||
# receives the same bytes.
|
||||
#
|
||||
# Dependencies: bash, tar, sha256sum (or shasum -a 256), git. macOS + Linux compatible.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ---- locate repo root ------------------------------------------------------
|
||||
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || true)"
|
||||
if [ -z "${REPO_ROOT}" ] || [ ! -d "${REPO_ROOT}/.git" ]; then
|
||||
echo "ERROR: must run inside the boilerplate git repo." >&2
|
||||
exit 1
|
||||
fi
|
||||
cd "${REPO_ROOT}"
|
||||
|
||||
# ---- pick sha256 binary ----------------------------------------------------
|
||||
if command -v sha256sum >/dev/null 2>&1; then
|
||||
SHA256="sha256sum"
|
||||
elif command -v shasum >/dev/null 2>&1; then
|
||||
SHA256="shasum -a 256"
|
||||
else
|
||||
echo "ERROR: need sha256sum or shasum on PATH." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ---- destination -----------------------------------------------------------
|
||||
SHORT_SHA="$(git rev-parse --short HEAD)"
|
||||
DATE_ISO="$(date -u +%Y-%m-%d)"
|
||||
OUT_DIR="artifacts/plugin-audit/${DATE_ISO}"
|
||||
ARCHIVE_NAME="plugin-audit-${SHORT_SHA}.tar.gz"
|
||||
ARCHIVE_PATH="${OUT_DIR}/${ARCHIVE_NAME}"
|
||||
MANIFEST_PATH="${OUT_DIR}/MANIFEST-${SHORT_SHA}.txt"
|
||||
STAGE_DIR="$(mktemp -d -t plugin-audit-XXXXXX)"
|
||||
trap 'rm -rf "${STAGE_DIR}"' EXIT
|
||||
|
||||
mkdir -p "${OUT_DIR}"
|
||||
|
||||
echo "→ Building plugin audit package"
|
||||
echo " repo: ${REPO_ROOT}"
|
||||
echo " HEAD: ${SHORT_SHA}"
|
||||
echo " out: ${ARCHIVE_PATH}"
|
||||
echo " stage: ${STAGE_DIR}"
|
||||
|
||||
# ---- in-scope file list ----------------------------------------------------
|
||||
# Append-only list. Keep aligned with docs/security/plugin-attack-surface.md § 1-6.
|
||||
# Each path is relative to the repo root. Glob patterns expanded by bash.
|
||||
INSCOPE_PATHS=(
|
||||
# Runtime
|
||||
"packages/plugin-runtime/src"
|
||||
"packages/plugin-runtime/package.json"
|
||||
"packages/plugin-runtime/tsconfig.json"
|
||||
|
||||
# SDK
|
||||
"packages/plugin-sdk/src"
|
||||
"packages/plugin-sdk/examples"
|
||||
"packages/plugin-sdk/package.json"
|
||||
"packages/plugin-sdk/tsconfig.json"
|
||||
|
||||
# Worker handlers
|
||||
"apps/worker/src/jobs/plugin-invoke.ts"
|
||||
"apps/worker/src/jobs/plugin-invoke.test.ts"
|
||||
"apps/worker/src/jobs/plugin-capability-use.ts"
|
||||
"apps/worker/src/jobs/plugin-capability-use.test.ts"
|
||||
"apps/worker/src/jobs/plugin-audit-retention.ts"
|
||||
"apps/worker/src/jobs/plugin-audit-retention.test.ts"
|
||||
|
||||
# Web routes + lifecycle service. `$tenant` and `$id` here are literal
|
||||
# React Router path-segment names, NOT shell variables — we read array
|
||||
# elements without `eval` (see staging loop below) so they stay literal.
|
||||
'apps/web/app/routes/api.tenants.$tenant.plugins.tsx'
|
||||
'apps/web/app/routes/api.tenants.$tenant.plugins.test.ts'
|
||||
'apps/web/app/routes/app.$tenant/settings/plugins.tsx'
|
||||
'apps/web/app/routes/app.$tenant/settings/plugins.test.ts'
|
||||
'apps/web/app/routes/app.$tenant/settings/plugins.$id.audit.tsx'
|
||||
"apps/web/app/modules/plugins"
|
||||
|
||||
# CLI plugin commands
|
||||
"packages/cli/src/commands/plugins"
|
||||
|
||||
# Prisma schema for plugin tables
|
||||
"prisma/schema/plugins.prisma"
|
||||
|
||||
# Documentation
|
||||
"docs/security/plugin-threat-model.md"
|
||||
"docs/security/plugin-attack-surface.md"
|
||||
"docs/security/plugin-internal-findings.md"
|
||||
"docs/security/plugin-audit-rfp.md"
|
||||
"docs/security/plugin-runtime-signoff.md"
|
||||
"docs/architecture/plugin-system.md"
|
||||
"docs/architecture/plugin-hooks.md"
|
||||
"docs/plugins"
|
||||
"docs/improvement-plan/06-plugin-system"
|
||||
|
||||
# Env example (operator-visible config surface)
|
||||
".env.example"
|
||||
)
|
||||
|
||||
# ---- stage files -----------------------------------------------------------
|
||||
# We copy paths preserving directory structure under ${STAGE_DIR}/code/.
|
||||
PKG_ROOT="${STAGE_DIR}/plugin-audit-${SHORT_SHA}"
|
||||
mkdir -p "${PKG_ROOT}/code"
|
||||
|
||||
MISSING=()
|
||||
for path in "${INSCOPE_PATHS[@]}"; do
|
||||
# No eval / re-expansion — the path is taken literally. React Router
|
||||
# filenames contain literal `$tenant` / `$id` which we must NOT interpret
|
||||
# as shell variables.
|
||||
if [ ! -e "${path}" ]; then
|
||||
MISSING+=("${path}")
|
||||
continue
|
||||
fi
|
||||
parent_dir="$(dirname "${path}")"
|
||||
mkdir -p "${PKG_ROOT}/code/${parent_dir}"
|
||||
cp -R "${path}" "${PKG_ROOT}/code/${parent_dir}/"
|
||||
done
|
||||
|
||||
# ---- include git HEAD metadata --------------------------------------------
|
||||
git rev-parse HEAD > "${PKG_ROOT}/HEAD.txt"
|
||||
git log -1 --format="%H%n%an <%ae>%n%aI%n%s" > "${PKG_ROOT}/HEAD-meta.txt"
|
||||
git status --porcelain > "${PKG_ROOT}/WORKTREE-DIRTY.txt"
|
||||
if [ -s "${PKG_ROOT}/WORKTREE-DIRTY.txt" ]; then
|
||||
echo " WARNING: worktree is dirty — package reflects uncommitted state." >&2
|
||||
echo " See ${PKG_ROOT}/WORKTREE-DIRTY.txt inside the archive." >&2
|
||||
fi
|
||||
|
||||
# ---- readme inside the archive --------------------------------------------
|
||||
cat > "${PKG_ROOT}/README.txt" <<'PKG_README'
|
||||
Plugin Runtime External Audit Package
|
||||
=====================================
|
||||
|
||||
This archive contains the Phase 06 plugin runtime code surface plus the
|
||||
internal documentation we have produced. It is the input to the external
|
||||
pen-test described in docs/security/plugin-audit-rfp.md.
|
||||
|
||||
What's inside
|
||||
-------------
|
||||
|
||||
code/ Curated subset of the repo (see scripts/build-plugin-audit-package.sh
|
||||
for the in-scope list).
|
||||
HEAD.txt git HEAD SHA the archive was built from.
|
||||
HEAD-meta.txt Committer + date + subject of HEAD.
|
||||
WORKTREE-DIRTY.txt Uncommitted changes at build time (should be empty).
|
||||
MANIFEST.txt SHA-256 of every file in this archive.
|
||||
|
||||
Where to start reading
|
||||
----------------------
|
||||
|
||||
1. code/docs/security/plugin-audit-rfp.md — what we're asking for
|
||||
2. code/docs/security/plugin-threat-model.md — what we worry about
|
||||
3. code/docs/security/plugin-attack-surface.md — interface inventory
|
||||
4. code/docs/security/plugin-internal-findings.md — what we've already found
|
||||
5. code/packages/plugin-runtime/src — the runtime itself
|
||||
6. code/apps/worker/src/jobs/plugin-*.ts — worker entry points
|
||||
7. code/prisma/schema/plugins.prisma — data model
|
||||
|
||||
Re-test workflow
|
||||
----------------
|
||||
|
||||
After remediation lands on `main`, re-run the build script and send the
|
||||
new archive (with its delta vs. the previous SHORT_SHA).
|
||||
|
||||
PKG_README
|
||||
|
||||
# ---- per-file SHA-256 manifest --------------------------------------------
|
||||
(
|
||||
cd "${PKG_ROOT}"
|
||||
if [ "${SHA256}" = "sha256sum" ]; then
|
||||
find . -type f ! -name "MANIFEST.txt" -print0 | sort -z | xargs -0 sha256sum > MANIFEST.txt
|
||||
else
|
||||
# shasum -a 256 expects file args; use find -print0 + xargs
|
||||
find . -type f ! -name "MANIFEST.txt" -print0 | sort -z | xargs -0 shasum -a 256 > MANIFEST.txt
|
||||
fi
|
||||
)
|
||||
|
||||
# ---- pack ------------------------------------------------------------------
|
||||
tar -czf "${ARCHIVE_PATH}" -C "${STAGE_DIR}" "plugin-audit-${SHORT_SHA}"
|
||||
${SHA256} "${ARCHIVE_PATH}" > "${MANIFEST_PATH}"
|
||||
|
||||
# ---- summary --------------------------------------------------------------
|
||||
echo
|
||||
echo "✔ Archive built:"
|
||||
echo " ${ARCHIVE_PATH}"
|
||||
echo " $(wc -c < "${ARCHIVE_PATH}") bytes"
|
||||
echo
|
||||
echo "✔ Outer-archive SHA-256:"
|
||||
cat "${MANIFEST_PATH}"
|
||||
echo
|
||||
if [ ${#MISSING[@]} -gt 0 ]; then
|
||||
echo "⚠ Missing in-scope paths (omitted from archive):"
|
||||
for m in "${MISSING[@]}"; do echo " ${m}"; done
|
||||
fi
|
||||
echo
|
||||
echo "Next steps:"
|
||||
echo " 1. Verify the archive: tar -tzf ${ARCHIVE_PATH} | head"
|
||||
echo " 2. Email the archive to the vendor per docs/security/plugin-audit-rfp.md § 8."
|
||||
echo " 3. Record the archive checksum in your engagement tracker."
|
||||
Reference in new issue
Block a user