Compare commits

..

1 commit

Author SHA1 Message Date
dependabot[bot]
fb42947a9f
Merge f66f86349a into 082768ff51 2026-06-27 00:32:00 -04:00
2 changed files with 22 additions and 58 deletions

View file

@ -80,20 +80,10 @@ APP_ENV_LINK="${APP_DIR}/.env" # symlink -> ENV_FILE
SERVICE_USER="${SERVICE_USER:-openswe}"
SERVICE_GROUP="${SERVICE_GROUP:-${SERVICE_USER}}"
# Sea Haven owner guard inputs (applied after the store is read, below). The owner
# normally comes from SSM /open-swe-<env>/DEFAULT_REPO_OWNER; OPENSWE_REPO_OWNER is an
# explicit operator override that wins over the store. FORBIDDEN = the upstream org
# the fork must never target; SAFE = the fallback when the resolved owner is blank or
# forbidden. (Upper/lower + whitespace are normalized before the guard check.)
OPENSWE_REPO_OWNER="${OPENSWE_REPO_OWNER:-}"
FORBIDDEN_REPO_OWNER="langchain-ai"
# Fallback org when the resolved owner is blank/forbidden — PER-ENV (mirrors the
# iacManagedSsm owner) so a dev box can NEVER fall back into the real Sea Haven org;
# it stays isolated in its own dev org. Defends the blank/upstream cases in-env.
case "$ENV" in
dev) SAFE_REPO_OWNER="seahaven-open-swe-dev" ;;
*) SAFE_REPO_OWNER="Sea-Haven-Industries" ;;
esac
# Sea Haven override: upstream defaults DEFAULT_REPO_OWNER to "langchain-ai".
# For the Sea Haven deployment it MUST be the org. fetch-config forces this so a
# stale/blank SSM value can never point the agent at the upstream org.
SH_REPO_OWNER="${OPENSWE_REPO_OWNER:-Sea-Haven-Industries}"
for bin in aws jq; do
command -v "$bin" >/dev/null 2>&1 || { echo "fetch-config: '$bin' not found on PATH" >&2; exit 3; }
@ -201,30 +191,16 @@ while IFS=$'\t' read -r nb vb; do
done < <(batch_get_secrets_tsv)
log "loaded ${secret_count} secret(s) from Secrets Manager"
# --- Sea Haven DEFAULT_REPO_OWNER guard --------------------------------------
# OSWE-OWNER-04 (revised for multi-org): HONOR the configured owner — the
# OPENSWE_REPO_OWNER env override if set, else the store value — so per-env orgs
# work (dev = seahaven-open-swe-dev, prod = Sea-Haven-Industries). But GUARD the two
# values that must NEVER reach the agent: blank, and the upstream 'langchain-ai' org
# (the fork's origin). Either falls back to the Sea Haven org so a stale/blank/mis-set
# value can never point the agent upstream. Comparison is case- and whitespace-
# insensitive. The POSITIVE org allowlist is enforced by the app (ALLOWED_GITHUB_ORGS).
resolved_owner="${OPENSWE_REPO_OWNER:-${VARS[DEFAULT_REPO_OWNER]:-}}"
# Normalize for the guard CHECK ONLY (the original value is what gets stored when
# allowed): lowercase, strip whitespace, take the FIRST path segment so a value like
# 'langchain-ai/open-swe' still trips the guard, and drop dots (GitHub owners contain
# none) so 'langchain-ai.' can't slip past. Homoglyph/unicode variants are out of scope
# here — the owner comes from admin-written SSM/IaC, not attacker-controlled input.
norm_owner="$(printf '%s' "$resolved_owner" | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]')"
norm_owner="${norm_owner%%/*}"
norm_owner="${norm_owner//./}"
case "$norm_owner" in
"" | "$FORBIDDEN_REPO_OWNER")
log "WARNING: DEFAULT_REPO_OWNER ('${resolved_owner:-<blank>}') is blank or the upstream org -> forcing '${SAFE_REPO_OWNER}'"
resolved_owner="$SAFE_REPO_OWNER"
;;
esac
VARS[DEFAULT_REPO_OWNER]="$resolved_owner"
# --- Sea Haven DEFAULT_REPO_OWNER hard pin -----------------------------------
# T5 OSWE-OWNER-04: a HARD pin, not a deny-list. Whatever the store holds (blank,
# upstream 'langchain-ai', a case/space variant, or any other org), the owner is
# unconditionally forced to the Sea Haven org so the agent can never target the
# wrong owner.
cur_owner="${VARS[DEFAULT_REPO_OWNER]:-}"
if [ -n "$cur_owner" ] && [ "$cur_owner" != "$SH_REPO_OWNER" ]; then
log "WARNING: SSM DEFAULT_REPO_OWNER differs from the pinned org -> hard-pinning to '${SH_REPO_OWNER}'"
fi
VARS[DEFAULT_REPO_OWNER]="$SH_REPO_OWNER"
# --- FAIL-FAST: required vars -------------------------------------------------
# Hard-required regardless of mode:

View file

@ -123,21 +123,16 @@ export function iacManagedSsm(env: EnvName): Record<string, string> {
// recon: seahaven.com Route53 zone + *.seahaven.com ACM cert are live on the ALB
// — distinct from the on-prem seahavenind.com). dev = openswe-dev, prod = openswe.
const host = `https://openswe${env === "dev" ? "-dev" : ""}.seahaven.com`;
// Repo targeting is PER-ENV: dev drives the disposable sandbox repo in the
// dedicated seahaven-open-swe-dev org (isolates dev-agent activity from the real
// Sea Haven org); prod stays on the Sea Haven org pilot repo. fetch-config's owner
// GUARD honors this value (rejecting only blank / the upstream langchain-ai org).
const repo =
env === "dev"
? { owner: "seahaven-open-swe-dev", name: "openswe-dev-sandbox" }
: { owner: "Sea-Haven-Industries", name: "open-swe-pilot" };
const managed: Record<string, string> = {
return {
// Sandbox provider — plan keeps stock langsmith (T9). Stable.
SANDBOX_TYPE: "langsmith",
DEFAULT_REPO_OWNER: repo.owner,
// Repo-owner allowlist (comma list) — the env's org. The app gates triggers on this.
ALLOWED_GITHUB_ORGS: repo.owner,
DEFAULT_REPO_NAME: repo.name,
// Sea Haven org pin. fetch-config ALSO hard-pins this at boot, but owning the
// real value here keeps SSM self-consistent rather than blank.
DEFAULT_REPO_OWNER: "Sea-Haven-Industries",
// Repo allowlist (comma list) — the Sea Haven org. Stable/derivable.
ALLOWED_GITHUB_ORGS: "Sea-Haven-Industries",
// Pilot repo (project memory: Sea-Haven-Industries/open-swe-pilot).
DEFAULT_REPO_NAME: "open-swe-pilot",
// Dashboard URLs — derived from the public host.
DASHBOARD_BASE_URL: host,
DASHBOARD_API_BASE_URL: host,
@ -145,13 +140,6 @@ export function iacManagedSsm(env: EnvName): Record<string, string> {
// Primary builder model (project memory team_settings: anthropic:claude-opus-4-8).
LLM_MODEL_ID: "anthropic:claude-opus-4-8",
};
// Dev e2e smoke: seed the owner's user_mapping so an @openswe comment from the
// triggering GitHub login resolves (an unmapped commenter is silently skipped).
// Dev-only — prod seeds its mappings via its own operator config. login:email.
if (env === "dev") {
managed.SEED_USER_MAPPINGS = "amoussa1229:adam@seahavenind.com";
}
return managed;
}
/**