fix: preserve route limits and harden restore marker
This commit is contained in:
@@ -29,6 +29,10 @@ The web server checks the allowlist at the relevant boundary:
|
||||
- `/api/sync` and the application synchronizer check `asset_sync`.
|
||||
- `/api/session/token` checks `session_token`.
|
||||
- Character management and OAuth entry points check `identity`.
|
||||
- The root layout skips its authenticated session lookup only when every
|
||||
capability represented by the root assistant/navigation shell is disabled;
|
||||
if a separate asset, identity, session-token, subscription, or assistant
|
||||
capability remains enabled, it preserves the existing user session state.
|
||||
- The Convex browser status subscription checks `subscriptions`; sync bridge
|
||||
mutations check `asset_sync` in the backend authorization plane too. The
|
||||
allowlist is copied into Convex by `bun run convex:configure`; that setting
|
||||
|
||||
+63
-18
@@ -46,11 +46,40 @@ project="eden-restore-${USER:-operator}-$(date +%s)-$$"
|
||||
restore_project="${project}-restored"
|
||||
work="$(mktemp -d "${TMPDIR:-/tmp}/eden-restore.XXXXXX")"
|
||||
chmod 700 "$work"
|
||||
# Do not let an ambient shell, repository .env, or prior Compose project alter
|
||||
# this rehearsal. The explicit env file below contains only non-secret values;
|
||||
# synthetic key values are loaded separately from the mode-0600 key file.
|
||||
unset COMPOSE_FILE COMPOSE_ENV_FILES COMPOSE_PROJECT_NAME COMPOSE_PROFILES DOCKER_HOST APP_MODE APP_ORIGIN ORIGIN APP_RELEASE_ID APP_CAPABILITY_ALLOWLIST CONVEX_URL PUBLIC_CONVEX_URL CONVEX_SITE_ORIGIN CONVEX_PORT CONVEX_SITE_PORT WEB_PORT CONVEX_IMAGE CONVEX_DASHBOARD_IMAGE EVE_CALLBACK_URL EVE_CLIENT_ID EVE_CLIENT_SECRET ESI_USER_AGENT TYPESAFE_API_KEY APP_AUTH_ISSUER TOKEN_ENCRYPTION_KEY CONVEX_BRIDGE_SECRET APP_AUTH_PRIVATE_KEY APP_AUTH_JWKS CONVEX_SELF_HOSTED_URL CONVEX_SELF_HOSTED_ADMIN_KEY
|
||||
export CONVEX_BIND_ADDRESS=127.0.0.1 CONVEX_PORT=$((3200 + RANDOM % 500)) CONVEX_SITE_PORT=$((3700 + RANDOM % 500))
|
||||
export WEB_BIND_ADDRESS=127.0.0.1 WEB_PORT=$((4200 + RANDOM % 500))
|
||||
export APP_MODE=live APP_RELEASE_ID=restore-fixture APP_CAPABILITY_ALLOWLIST=asset_search,asset_valuation,asset_sync,assistant_dispatch,session_token,identity,subscriptions
|
||||
export APP_ORIGIN="http://127.0.0.1:$WEB_PORT" ORIGIN="$APP_ORIGIN" APP_AUTH_ISSUER="$APP_ORIGIN"
|
||||
export PUBLIC_CONVEX_URL="http://127.0.0.1:$CONVEX_PORT" CONVEX_SITE_ORIGIN="http://127.0.0.1:$CONVEX_SITE_PORT"
|
||||
export EVE_CALLBACK_URL="$APP_ORIGIN/auth/eve/callback"
|
||||
write_compose_env() {
|
||||
cat > "$work/compose.env" <<EOF
|
||||
COMPOSE_PROJECT_NAME=$project
|
||||
CONVEX_BIND_ADDRESS=127.0.0.1
|
||||
CONVEX_PORT=$CONVEX_PORT
|
||||
CONVEX_SITE_PORT=$CONVEX_SITE_PORT
|
||||
WEB_BIND_ADDRESS=127.0.0.1
|
||||
WEB_PORT=$WEB_PORT
|
||||
APP_MODE=$APP_MODE
|
||||
APP_RELEASE_ID=$APP_RELEASE_ID
|
||||
APP_CAPABILITY_ALLOWLIST=$APP_CAPABILITY_ALLOWLIST
|
||||
APP_ORIGIN=$APP_ORIGIN
|
||||
ORIGIN=$ORIGIN
|
||||
APP_AUTH_ISSUER=$APP_AUTH_ISSUER
|
||||
PUBLIC_CONVEX_URL=$PUBLIC_CONVEX_URL
|
||||
CONVEX_SITE_ORIGIN=$CONVEX_SITE_ORIGIN
|
||||
EVE_CALLBACK_URL=$EVE_CALLBACK_URL
|
||||
EOF
|
||||
}
|
||||
write_compose_env
|
||||
compose() { docker compose --project-directory "$repo" --file "$repo/compose.yaml" --env-file "$work/compose.env" "$@"; }
|
||||
cleanup() {
|
||||
docker compose -p "$project" down -v >/dev/null 2>&1 || true
|
||||
docker compose -p "$restore_project" down -v >/dev/null 2>&1 || true
|
||||
compose -p "$project" down -v >/dev/null 2>&1 || true
|
||||
compose -p "$restore_project" down -v >/dev/null 2>&1 || true
|
||||
# Export/copy the evidence bundle before this cleanup; the temporary key and
|
||||
# archives are intentionally removed only after retention is recorded.
|
||||
rm -rf "$work"
|
||||
@@ -58,13 +87,18 @@ cleanup() {
|
||||
trap cleanup EXIT
|
||||
(cd "$work" && bun "$repo/scripts/generate-keys.ts")
|
||||
chmod 600 "$work/.env.keys"
|
||||
set -a
|
||||
. "$work/.env.keys"
|
||||
set +a
|
||||
```
|
||||
|
||||
Load only those synthetic values into a temporary shell environment. Set
|
||||
`APP_MODE=demo`, `APP_RELEASE_ID=restore-fixture`,
|
||||
`APP_CAPABILITY_ALLOWLIST=asset_search,asset_valuation,asset_sync,assistant_dispatch,session_token,identity,subscriptions`,
|
||||
and an issuer such as `http://127.0.0.1:18080`. Do not use a production
|
||||
callback or provider key.
|
||||
The bootstrap above loads only synthetic values into a temporary shell
|
||||
environment and writes the explicit Compose env file. It allocates loopback
|
||||
backend, site, web, issuer, public URL, and callback origins together; when
|
||||
restore ports change, update all corresponding exported values before starting
|
||||
the restored project. The Compose web service intentionally uses the
|
||||
service-internal `http://backend:3210`; only host/public settings use the
|
||||
allocated loopback ports. Do not use a production callback or provider key.
|
||||
|
||||
## Backup rehearsal
|
||||
|
||||
@@ -73,7 +107,7 @@ callback or provider key.
|
||||
|
||||
```sh
|
||||
export COMPOSE_PROJECT_NAME="$project"
|
||||
docker compose -p "$project" up -d backend
|
||||
compose -p "$project" up -d backend
|
||||
volume="${project}_convex-data"
|
||||
mount="$(docker volume inspect -f '{{ .Mountpoint }}' "$volume")"
|
||||
source_bytes_before="$(du -sb "$mount" | awk '{print $1}')"
|
||||
@@ -87,9 +121,9 @@ callback or provider key.
|
||||
key fingerprint or assume an image-specific helper command:
|
||||
|
||||
```sh
|
||||
read -r -s CONVEX_SELF_HOSTED_ADMIN_KEY
|
||||
export CONVEX_SELF_HOSTED_ADMIN_KEY
|
||||
CONVEX_SELF_HOSTED_URL=http://127.0.0.1:"$CONVEX_PORT" \
|
||||
read -r -s admin_key
|
||||
CONVEX_SELF_HOSTED_ADMIN_KEY="$admin_key" \
|
||||
CONVEX_SELF_HOSTED_URL="http://127.0.0.1:$CONVEX_PORT" \
|
||||
bun "$repo/scripts/configure-convex.ts" >/dev/null
|
||||
```
|
||||
|
||||
@@ -111,19 +145,25 @@ callback or provider key.
|
||||
```sh
|
||||
export RESTORE_MARKER="$(date -u +%Y%m%dT%H%M%SZ)-synthetic"
|
||||
export RESTORE_MARKER_CHARACTER_ID=998000001
|
||||
SMOKE_ALLOW_WRITE=1 RESTORE_MARKER="$RESTORE_MARKER" \
|
||||
SMOKE_ALLOW_WRITE=1 RESTORE_MARKER_CONFIRMATION=DISPOSABLE_LOOPBACK_ONLY \
|
||||
RESTORE_MARKER_PHASE=write RESTORE_MARKER="$RESTORE_MARKER" \
|
||||
RESTORE_MARKER_CHARACTER_ID="$RESTORE_MARKER_CHARACTER_ID" \
|
||||
CONVEX_SELF_HOSTED_URL=http://127.0.0.1:"$CONVEX_PORT" \
|
||||
CONVEX_SELF_HOSTED_URL="http://127.0.0.1:$CONVEX_PORT" \
|
||||
bun "$repo/scripts/smoke-restore-marker.ts" | tee "$work/marker-write.log"
|
||||
```
|
||||
|
||||
The marker tool defaults to non-writing verification, rejects non-loopback
|
||||
targets before constructing a backend client, and requires both the explicit
|
||||
write phase and `DISPOSABLE_LOOPBACK_ONLY` confirmation. Never reuse the
|
||||
marker command against a shared, staging, or production URL.
|
||||
|
||||
4. Create a consistent filesystem backup while the disposable backend is
|
||||
stopped. The Convex data volume contains the backend data and instance
|
||||
credential material; back up it as one unit. A host administrator may need
|
||||
root access to the Docker volume mount.
|
||||
|
||||
```sh
|
||||
docker compose -p "$project" stop backend
|
||||
compose -p "$project" stop backend
|
||||
tar --xattrs --acls --numeric-owner -C "$mount" \
|
||||
-czf "$work/convex-data.tar.gz" .
|
||||
sha256sum "$work/convex-data.tar.gz" > "$work/convex-data.tar.gz.sha256"
|
||||
@@ -151,6 +191,10 @@ callback or provider key.
|
||||
tar --xattrs --acls --numeric-owner -C "$restore_mount" \
|
||||
-xzf "$work/convex-data.tar.gz"
|
||||
export CONVEX_PORT=$((5200 + RANDOM % 500)) CONVEX_SITE_PORT=$((5700 + RANDOM % 500)) WEB_PORT=$((6200 + RANDOM % 500))
|
||||
export APP_ORIGIN="http://127.0.0.1:$WEB_PORT" ORIGIN="$APP_ORIGIN" APP_AUTH_ISSUER="$APP_ORIGIN"
|
||||
export PUBLIC_CONVEX_URL="http://127.0.0.1:$CONVEX_PORT" CONVEX_SITE_ORIGIN="http://127.0.0.1:$CONVEX_SITE_PORT"
|
||||
export EVE_CALLBACK_URL="$APP_ORIGIN/auth/eve/callback"
|
||||
write_compose_env
|
||||
```
|
||||
|
||||
2. Start the restored backend under the second project and configure the web
|
||||
@@ -160,8 +204,9 @@ callback or provider key.
|
||||
instance-credential continuity is unproven and traffic must remain closed:
|
||||
|
||||
```sh
|
||||
docker compose -p "$restore_project" up -d backend
|
||||
CONVEX_SELF_HOSTED_URL=http://127.0.0.1:"$CONVEX_PORT" \
|
||||
compose -p "$restore_project" up -d backend
|
||||
CONVEX_SELF_HOSTED_ADMIN_KEY="$admin_key" \
|
||||
CONVEX_SELF_HOSTED_URL="http://127.0.0.1:$CONVEX_PORT" \
|
||||
bun "$repo/scripts/configure-convex.ts" >/dev/null
|
||||
```
|
||||
|
||||
@@ -169,9 +214,9 @@ callback or provider key.
|
||||
the synthetic Convex smoke with fresh IDs:
|
||||
|
||||
```sh
|
||||
SMOKE_ALLOW_WRITE=1 RESTORE_MARKER="$RESTORE_MARKER" \
|
||||
RESTORE_MARKER="$RESTORE_MARKER" \
|
||||
RESTORE_MARKER_CHARACTER_ID="$RESTORE_MARKER_CHARACTER_ID" \
|
||||
CONVEX_SELF_HOSTED_URL=http://127.0.0.1:"$CONVEX_PORT" \
|
||||
CONVEX_SELF_HOSTED_URL="http://127.0.0.1:$CONVEX_PORT" \
|
||||
RESTORE_MARKER_PHASE=verify bun "$repo/scripts/smoke-restore-marker.ts"
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user