mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-10-07 16:19:09 +00:00
Compare commits
2 commits
fb42947a9f
...
d2ecb64fb2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2ecb64fb2 | ||
|
|
5e30bc6be2 |
2 changed files with 58 additions and 22 deletions
|
|
@ -80,10 +80,20 @@ APP_ENV_LINK="${APP_DIR}/.env" # symlink -> ENV_FILE
|
|||
SERVICE_USER="${SERVICE_USER:-openswe}"
|
||||
SERVICE_GROUP="${SERVICE_GROUP:-${SERVICE_USER}}"
|
||||
|
||||
# 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}"
|
||||
# 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
|
||||
|
||||
for bin in aws jq; do
|
||||
command -v "$bin" >/dev/null 2>&1 || { echo "fetch-config: '$bin' not found on PATH" >&2; exit 3; }
|
||||
|
|
@ -191,16 +201,30 @@ 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 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"
|
||||
# --- 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"
|
||||
|
||||
# --- FAIL-FAST: required vars -------------------------------------------------
|
||||
# Hard-required regardless of mode:
|
||||
|
|
|
|||
|
|
@ -123,16 +123,21 @@ 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`;
|
||||
return {
|
||||
// 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> = {
|
||||
// Sandbox provider — plan keeps stock langsmith (T9). Stable.
|
||||
SANDBOX_TYPE: "langsmith",
|
||||
// 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",
|
||||
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,
|
||||
// Dashboard URLs — derived from the public host.
|
||||
DASHBOARD_BASE_URL: host,
|
||||
DASHBOARD_API_BASE_URL: host,
|
||||
|
|
@ -140,6 +145,13 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue