Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/audit-deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
python3 -m pip install --require-hashes --only-binary=:all: -r scripts/v2/agentcore/requirements-provision.txt
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.15.7
terraform_version: 1.17.1
terraform_wrapper: false
- name: Check context and configured account before OIDC
id: scope
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/collect-runtime.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
python-version: "3.12"
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.15.7
terraform_version: 1.17.1
terraform_wrapper: false
- name: Validate configured development account
run: python3 scripts/v2/ci_runtime_policy.py verify-role
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-guide.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:

- uses: actions/setup-node@v4
with:
node-version: 20
node-version: 26
cache: npm
cache-dependency-path: docs-site/package-lock.json

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-migrations.yml
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ jobs:

- uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.15.7
terraform_version: 1.17.1
terraform_wrapper: false

- name: Validate development role
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-web.yml
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ jobs:

- uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.15.7
terraform_version: 1.17.1
terraform_wrapper: false

- name: Select the branch's stack (fail-closed — no cross-branch fallback)
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/merge-verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:

- uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.15.7
terraform_version: 1.17.1
terraform_wrapper: false

- name: Install web dependencies
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/terraform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ jobs:

- uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.15.7
terraform_version: 1.17.1
terraform_wrapper: false

- name: Restore backend.hcl / terraform.tfvars
Expand Down Expand Up @@ -680,7 +680,7 @@ jobs:

- uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.15.7
terraform_version: 1.17.1
terraform_wrapper: false

- name: Select the branch's stack (fail-closed)
Expand Down
8 changes: 4 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!-- generated-by: co-agent · source: CLAUDE.md · claude-md-sha: 83a922d55538 · generated-at: 2026-11-03 · DO NOT EDIT — edit CLAUDE.md then run /co-agent sync-context -->
<!-- generated-by: co-agent · source: CLAUDE.md · claude-md-sha: dc89ee9e7504 · generated-at: 2026-11-04 · DO NOT EDIT — edit CLAUDE.md then run /co-agent sync-context -->

> You are an external reviewer for this repo — project context below, distilled from CLAUDE.md. This file is shared verbatim by the external review panel (not a per-AI copy).

Expand All @@ -17,9 +17,9 @@ v2 = ops dashboard + AI diagnosis. **Current form = diagnosis + remediation *pro
- **Flag any PR that enables mutation/autonomy/BYO-MCP** by flipping a frozen flag or wiring dark substrate live. Hardening an already-shipped connection path does not grant a new policy exception. `CUSTOM_MCP_ENABLED` defaults OFF in web and runtime until dated acceptance and a separately reviewed release. Flag weakened administrator authorization, egress/read, explicit account membership, exact tool ceilings, locked confirmation, durable audit, current row-bound Secret versions or SSRF guards, and alternate live MCP endpoint paths that bypass them.

## Stack / runtime
- **Web:** Next.js 15 / React 19 thin-BFF (`web/`), standalone **arm64**, root path `/` — no basePath. Fetch is `/api/*` (never `/awsops/api/*`). Heavy/long/OOM work is enqueued to the worker tier — BUT the generic `POST /api/jobs` accepts **only allowlisted noop job types**; domain jobs (`report`, `compliance`, etc.) are submitted only via their ownership-checked dedicated routes (`/api/diagnosis`, `/api/compliance/run` — IDOR fix, ADR-009).
- **Web:** Next.js 16 / React 19 thin-BFF (`web/`), standalone **arm64**, root path `/` — no basePath. Fetch is `/api/*` (never `/awsops/api/*`). Heavy/long/OOM work is enqueued to the worker tier — BUT the generic `POST /api/jobs` accepts **only allowlisted noop job types**; domain jobs (`report`, `compliance`, etc.) are submitted only via their ownership-checked dedicated routes (`/api/diagnosis`, `/api/compliance/run` — IDOR fix, ADR-009).
- **Data:** Aurora Serverless v2 (PG 17.9) via node-pg (`web/lib/db.ts`, shared `getPool`). App state in Aurora, **not `data/*.json`** (v1 pattern). Schema = `terraform/foundation/data/schema.sql` + ULID migrations (`migrations/<ULID>_*.sql`, never append to schema.sql — a migration's `-- since:` header is checksum-immutable once merged, never retag it).
- **IaC:** Terraform only (CDK dropped). Single root `terraform/foundation/`, partial S3 backend (`backend.hcl`, no DynamoDB), TF ≥1.15, provider `~>6.0`.
- **IaC:** Terraform only (CDK dropped). Single root `terraform/foundation/`, partial S3 backend (`backend.hcl`, no DynamoDB), TF ≥1.17.1, provider `~>6.0`.
- **Edge:** CloudFront(TLS) → VPC Origin `https-only:443` → internal ALB HTTPS:443 (regional ACM) → HTTP → Fargate `awsops-v2-web:3000`. **No public ALB.** ALB SG allows 443 from `CloudFront-VPCOrigins-Service-SG` (VPC-CIDR-only → 504).
- **AI:** Bedrock Claude: Sonnet-class default, Opus-class AI Diagnosis Deep option, Haiku-class routing/helpers (model IDs live in code) + AgentCore (Strands, `agent/agent.py`, routes via `GATEWAYS_JSON`). Live AWS queries via AgentCore MCP Lambda tools (`agent/lambda/*.py`), never inline in the BFF. Config source of truth = SSM `/ops/awsops-v2/agentcore/{runtime_arn,interpreter_id,memory_id}` (runtime read; no ECS `valueFrom`).
- **Chat routing (LIVE):** regex fast-path (`web/lib/route.ts`, first-match-wins RULES) → Haiku classifier fallback; gated by `hybrid_routing_enabled`. **16 routing keys are registered** = 9 gateway-routed sections + `aws-data` + 6 auto-collect collectors (`web/lib/collectors/`); the latter 7 are web-BFF-local (not via AgentCore) and their Steampipe-backed execution is hard-disabled — they fail-open to normal routing at runtime.
Expand Down Expand Up @@ -55,7 +55,7 @@ make workers # arm64 worker image push (after apply with workers_enabled=tru
```
Dev Deploy Web requires readonly producer/ECR proof before migrations and promotes only that same digest. Dev Deploy AgentCore and current-source dev Deploy Web require the reusable private `deploy-migrations.yml` workflow before provisioning or image promotion. Guarded dev web pushes run it automatically; explicit older-image rollback requires producer/schema acknowledgement and runs no DDL. Every dev web release verifies the exact ECS/image deployment, then full runtime readiness including login/DB; the compatibility input cannot disable these checks. This is operator CI under ADR-005, not product autonomy. It requires `CI_MIGRATIONS_ENABLED_DEV=true` and applied `ci_migrations_enabled=true` with a non-null `migration_job` output before release. Main/preview and direct private-host CLI retain `make migrate`
before `make agentcore`. Migrations and reader password sync always precede AgentCore provisioning. Private migration offline `scripts/v2/ci/*.test.mjs` fixtures require locked Node dependencies, Python PyYAML and boto3/botocore (`pip install -r agent/requirements.txt`), and Terraform
1.15.7; runtime/controller/workflow and mock-plan checks make no AWS calls. The three PostgreSQL suites above require bare `docker` on PATH, a reachable daemon and OpenSSL, with no automatic `sudo`/`DOCKER` override. The web connection-phase and policy suites
1.17.1; runtime/controller/workflow and mock-plan checks make no AWS calls. The three PostgreSQL suites above require bare `docker` on PATH, a reachable daemon and OpenSSL, with no automatic `sudo`/`DOCKER` override. The web connection-phase and policy suites
additionally use the locked web driver and TypeScript dependencies. All three PostgreSQL suites are fail-hard exceptions to legacy optional `scripts/v2/*.itest.mjs`; missing Docker is never a skip.

No repo-root `package.json` — the only one outside `web/`/`docs-site/` is `scripts/v2/package.json` (`make deps` runs `npm ci --prefix scripts/v2`). `next build` fails on app-level type errors but `*.test.ts(x)` type noise is non-blocking.
Expand Down
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- Web framework security update: Next.js 15.5.25 and React 19 use async request parameters and cookies while preserving authentication, ownership checks, redirects and standalone deployment. Upgrade Vitest/Vite and patched transitive dependencies.
- Web framework and runtime refresh: Next.js 16.4.5, React 19.3.1 and Node 26.13.0 retain authentication, ownership checks and standalone deployment; the request body guard uses the Next.js proxy convention. Refresh JavaScript/Python dependencies and AgentCore SDKs with compatibility pins, Terraform 1.17.1/provider locks, and Python 3.14 Lambda/container runtimes. Update documentation security dependencies and Mermaid 12 while preserving all four locales. Preserve gateway authentication, feature gates and release safeguards.

- Configuration topology evidence: independently scoped EKS/ECS candidates require active pods or RUNNING tasks; Succeeded/Failed pods and STOPPED/DELETED tasks cannot claim reused IPs, while unknown states and conflicting references remain unverified. Duplicate IPs across clusters in one region/VPC are withheld even when names match. Unreadable known scopes block matching IPs; unknown or truncated EKS enumeration withholds account-wide ownership. Saved account/region/global-resource scope, generation/cancellation guards and same-scope retained-graph notices protect partial refreshes; complete empty results replace prior data. All inventory and enrichment reads share two lanes per load, with sequential critical paging (20 × 500 rows) and the shared 30-second browser deadline. Each page requires the single-statement rows/ledger snapshot marker and stable global sweep metadata; ownership never depends on a browser/database clock comparison. Aggregate sweep health, read failures and per-account uncertainty remain distinct. EKS runs only for exact host scope; member/all scopes show non-enumeration reasons. Unconnected clusters use cluster_not_connected rather than a read-failure reason, while their scopes still block unknown ownership. Region metadata is validated. Inventory follows that full scope, and genuine row caps use the configured limits; an incomplete first page does not claim the full cap. Capture ranges and the Refresh freshness chip use source/eligible last-success timestamps in viewer-local time, so rereading old data does not make it fresh. Cached target labels, target-group-only targetCapturedAt and SQL-projection limits remain explicit; no AWS mutation or projection/grant change.
- Runtime IAM narrowing applies on the next Terraform apply to every already-enabled stack, including main, independently of the dev profile: exact three web SSM parameters, runtime discovery/token actions, own-cluster task control and Claude-only model resources. Read conditions include known regions, including future opt-ins. Host-only account registration rejects foreign accounts with HTTP 409; dev host-only configuration requires the verified profile.
Expand Down Expand Up @@ -785,7 +785,7 @@ First release of the **v2 line** (versioned independently from the v1 1.x line,

### Changed

- 웹 프레임워크 보안 업데이트: Next.js 15.5.25와 React 19의 비동기 요청 파라미터·쿠키 API를 적용하고 인증·소유권 검사·리다이렉트·standalone 배포를 유지합니다. Vitest/Vite와 취약한 전이 의존성을 패치 버전으로 올립니다.
- 웹 프레임워크·런타임 최신화: Next.js 16.4.5, React 19.3.1, Node 26.13.0으로 인증·소유권 검사·standalone 배포를 유지하고 요청 본문 제한을 Next.js proxy 규약으로 옮깁니다. 호환성 버전 고정과 함께 JavaScript/Python 의존성·AgentCore SDK, Terraform 1.17.1·provider 잠금파일, Python 3.14 Lambda·컨테이너 런타임을 갱신합니다. 문서 사이트의 보안 의존성과 Mermaid 12를 갱신하고 4개 언어를 유지합니다. Gateway 인증·기능 게이트·릴리스 보호 장치는 유지합니다.

- 구성 토폴로지 근거: EKS/ECS 후보는 독립적인 범위 확인과 활성 Pod 또는 RUNNING 태스크 근거를 요구합니다. Succeeded/Failed Pod와 STOPPED/DELETED 태스크는 재사용 IP를 점유하지 않으며 미확인 상태·참조 충돌은 확정하지 않습니다. 같은 리전·VPC의 여러 클러스터에서 같은 IP가 나오면 이름이 같아도 보류합니다. 읽을 수 없는 확인된 범위의 IP를 차단하며 EKS 범위 미확인이나 열거 제한 시 전체 소유권을 보류합니다. 저장된 계정·리전·전역 리소스 범위와 세대·취소 검증, 같은 범위의 이전 그래프 유지 안내를 보존하며 완전한 빈 결과는 교체합니다. 모든 인벤토리·이름 보강 조회는 로드마다 두 실행 경로를 공유하고 중요 타입은 각 경로에서 순차 페이지 조회(20 × 500행)를 수행하며 브라우저의 30초 제한을 유지합니다. 페이지마다 한 SQL 문으로 읽은 행·원장의 스냅샷 표시와 동일한 전역 수집 버전을 요구하고, 소유권 판단에 브라우저·DB 시계 비교를 쓰지 않습니다. 집계 수집 상태·조회 실패·계정별 미확인을 구분합니다. EKS는 정확한 호스트 범위에서만 조회하며 멤버·전체 범위의 미조회 사유를 표시합니다. 미연결 클러스터는 조회 실패 대신 cluster_not_connected로 구분하되 해당 범위의 소유권은 계속 보류하고 리전 메타데이터를 검증합니다. 인벤토리는 해당 전체 범위를 사용하며 실제 행 상한은 설정값에서 계산하고 불완전한 첫 페이지를 전체 상한으로 표시하지 않습니다. 수집 시각 범위와 Refresh의 최신성 표시는 원본·허용된 최근 성공 시각을 사용자 시간대로 사용하므로 오래된 데이터를 다시 조회해도 새 데이터가 되지 않습니다. 캐시 대상 이름, 대상 그룹 전용 targetCapturedAt 및 SQL 투영 한계를 유지하며 AWS 변경이나 투영·권한 변경은 없습니다.
- 런타임 IAM 축소는 dev 프로필과 무관하게 main을 포함한 기존 활성 스택의 다음 Terraform apply에 적용됩니다. 웹 SSM 세 파라미터·런타임 조회/토큰 동작·자체 클러스터 태스크 제어·Claude 모델만 허용하며 알려진 리전(이후 opt-in 포함)을 읽기 조건에 포함합니다. 호스트 전용 계정 등록은 외부 계정을 HTTP 409로 거부하고 dev 호스트 모드는 검증된 프로필을 요구합니다.
Expand Down
Loading