Architecture / Deployment

AWS Deployment & App Owner Self-Service Plan

Defines the target AWS infrastructure, the three-sprint delivery sequence (NX-S18 through NX-S20), and the self-service capability model that allows app owners to build and operate pipelines entirely through the Nexus interface — without database or code access.

ADP-1.0 2026-05-08 Authority: Tier 3 Owner: Uued Viljapuuaiad

1. Objective

Deploy Nexus to AWS and expose all pipeline-building capabilities to app owners through the Orchestrator interface. App owners interact exclusively through:

App owners have no database access and no code access. All pipeline creation, configuration, running, and monitoring is done through the canvas editor, the node property forms, and the App Management page.

This document supersedes the informal plan discussed in session 2026-05-08 and is the authoritative reference for sprint scope, acceptance criteria, and infrastructure specification for NX-S18, NX-S19, and NX-S20.

Prerequisite Reading

Before acting on this document, read the following in order (per NEXUS_DOC_HIERARCHY.html Tier 1-3 protocol):

  1. NEXUS_COMPONENT_STATUS.html Section 8.1 — full inventory of what the Orchestrator canvas already does. Do not treat canvas capabilities as missing before reading this.
  2. NEXUS_CAPABILITY_GAP_ANALYSIS.md (GAP-2.0) Section 5-6 — GAP-11, GAP-12, GAP-13 are the UI-layer gaps. Engine-layer gaps (GAP-01..10) are mostly resolved.
  3. NEXUS_LLD.md Section 3.3.1 + Section 4 + Section 13 — target data-flow design and hardcoded-data elimination checklist.
  4. NEXUS_ROADMAP.md Section 9 (O6 milestone)app_catalog API is fully spec'd; NX-S18-WP1/WP2 implement it.

2. Current Platform State

The following capabilities are already implemented as of NX-S17 (Gate 11: 130/130 PASS). The AWS deployment plan builds on these, not around them.

2.1 Engine (Wormwood)

ComponentStatusKey Facts
FastAPI App + Pipeline RoutesProduction2,936 lines combined. Full pipeline CRUD, run, SSE telemetry, org/team/user management.
Rule Engine + Formula ParserProduction874 rules across 25 JSON files. 11 operators, 2 evaluation modes.
BDT ValidatorProduction21 registered types, lifecycle enforcement.
API Key Store + AuthProduction248 + 135 lines. API key auth on all routes requiring auth.
36 Node ExecutorsImplementedAll 36 nodes implemented and tested. HttpForward, AiTransform, HumanGate, SchedulerTrigger, WebhookTrigger, SmsIngest/Reply, PdfGenerator, FieldMapper, GraphBuild, and 27 others.
Orchestration EngineImplementedDAG execution, gate suspension/resume, revision loop. 316 lines.
Admin PanelProductionFlask 3. CRUD for all entities on port 8011. Internal tool only.
Local RuntimeProductionDefault execution mode. SQLite in dev, PostgreSQL target for prod.
Lambda HandlerScaffoldwormwood/api/lambda_handler.py — 19 lines. Shell only. NX-S19 completes.

2.2 Orchestrator Canvas (WORMWOOD_APP.html)

CapabilityStatusAPI Wired To
Node palette (44 types), drag-and-drop to canvasProductionNode type registry
Edge drawing between node pinsProduction— (client-side)
Load pipeline graph from engineProductionGET /pipelines/{id}
Save pipeline to engineProductionPUT /pipelines/{id}
Create new pipelineProductionPOST /pipelines
Run pipeline + SSE live animationProductionPOST /pipelines/{id}/run + SSE stream
Run history + per-node logsProductionGET /pipelines/{id}/runs
Node property editor (breadcrumb nav)Production— (generic shell)
Classes / Properties / Rules level tabsProductionGET /types, GET /rules
Per-node-type property field schemasPartialNX-S18-WP4 GAP-11
App catalog card grid (dynamic)HardcodedNX-S18-WP2 GAP-12
API key management UIMissingNX-S18-WP3

3. AWS Target Architecture

Resource Naming Convention (Live — eu-west-2, account 654654215330)

All AWS resources in the live deployment use the prefix nexus-prod- regardless of the DNS environment label. The DNS subdomain nexus-dev.codezerogroup.com reflects product maturity (development-stage product), not a separate AWS environment tier. There is a single AWS environment; its resources carry the -prod label because they are the sole production-grade deployment of this product at this time. The two labels are independent and do not map to each other.

ComponentDoc saysLive AWS name
ECS clusternexus-engine-svc clusternexus-prod
ECS task definitionnexus-enginenexus-prod-engine:1
ALB(unnamed in §3.1)nexus-prod-alb
Secrets Manager (API key)Secrets Manager (generic)nexus/prod/api-key-jUmQyN (field: api_key)
Secrets Manager (DB URL)Secrets Manager (generic)nexus/prod/db-XqDtrO (field: url)
S3 — SPA hostingnexus-staticnexus-nsd-packages (see note)
S3 — NSD packagesnexus-nsd-packagesnexus-nsd-packages

S3 note: nexus-static is taken in the global S3 namespace by a different AWS account. The SPA is hosted in nexus-nsd-packages under a /nexus-ui/ key prefix until a dedicated bucket is provisioned. nexus-deploy-agent IAM policy permits s3:CreateBucket only for pre-approved bucket names (currently: nexus-nsd-packages). See KNOWN_ISSUES ISSUE-072.

Target Stack: Cloud-Native SaaS

The target deployment is the Cloud-Native SaaS combination from NEXUS_DEPLOYMENT_MATRIX.html Section 4: C: aws-lambda + M: postgresql + V: chameleonv2-react + O: aws-step-functions. For initial deployment (NX-S19), the controller runs on ECS Fargate (not Lambda) to avoid cold-start latency on the SSE telemetry stream. Lambda migration (using the existing scaffold in lambda_handler.py) is a Phase 4 item.

3.1 Infrastructure Components

Network Layer

VPCSingle VPC with two availability zones. Public subnets for ALB. Private subnets for ECS tasks and RDS.
Security GroupsALB SG: inbound 443 from 0.0.0.0/0. Engine SG: inbound 8010 from ALB SG only. Admin SG: inbound 8011 from VPN/bastion only. RDS SG: inbound 5432 from Engine SG only.
ALBApplication Load Balancer. HTTPS termination. Routes /api/* to engine target group (port 8010). Routes /admin/* to admin target group (port 8011). Routes /nexus-ui/* to S3 static hosting.

Compute Layer

ECS FargateTwo task definitions: nexus-engine (Wormwood FastAPI, port 8010, 1 vCPU / 2GB RAM) and nexus-admin (Flask admin panel, port 8011, 0.5 vCPU / 1GB RAM). Both run in private subnets. Auto-scaling on CPU utilisation (70% threshold).
ECRTwo repositories: nexus/engine and nexus/admin. CI pipeline pushes tagged images on merge to main.
Lambda (future)The existing wormwood/api/lambda_handler.py scaffold enables eventual Lambda migration. Not in NX-S19 scope — Fargate is the initial target.

Data Layer

RDS PostgreSQLdb.t3.medium multi-AZ. Replaces SQLite in the production environment. Alembic migration runs in ECS task at deploy time. Separate databases per environment (prod / staging / dev).
S3Two buckets: nexus-nsd-packages (NSD versioned packages, lifecycle rules retain last 10 versions) and nexus-static (SPA HTML/CSS/JS, served via ALB or CloudFront). Both with versioning enabled.
Secrets ManagerDB credentials, Wormwood master API key, external service keys (Twilio, Anthropic, OpenAI). Accessed via IAM role from ECS tasks — no secrets in environment variables or container images.

CI/CD Pipeline

TriggerPush to main branch (protected, requires PR + passing tests).
BuildRun 2,712 tests (pytest). Build Docker images. Push to ECR with Git SHA tag + latest.
DeployUpdate ECS service to new image tag. Run Alembic migrations in a one-off ECS task before traffic switches. Blue/green deployment (ECS rolling update).
IaCTerraform (or CloudFormation) manages all infrastructure as code. State stored in S3 + DynamoDB lock table. No console-only resources.

3.2 DNS and Domain

EndpointTargetAuth
api.nexus-dev.codezerogroup.comALB → nexus-engine (port 8010)API key header X-API-Key
admin.nexus-dev.codezerogroup.comALB → nexus-admin (port 8011)Session auth, VPN-restricted
app.nexus-dev.codezerogroup.comALB → S3 static / CloudFrontAPI key (stored in browser nexus-login.key)
mcp.nexus-dev.codezerogroup.comALB → nexus-engine /mcp/*API key header, MCP transport (SSE + HTTP)

3.3 REST API Integration

App owners and external tools integrate with the engine via REST over HTTPS. Auth is via X-API-Key header (or api_key query param for SSE EventSource connections). Keys are DB-backed, scoped per org, and returned raw exactly once at creation.

Full integration reference: NEXUS_INTEGRATION_GUIDE.html. OpenAPI spec and Swagger UI: https://api.nexus-dev.codezerogroup.com/docs.

Note: MCP endpoint routes are not present in this deployment. MCP is a separate system (Nexus1) on an unrelated domain.


4. App Owner Self-Service Model

An app owner is a person who has been provisioned a tenant on the Nexus platform. They have an API key and access to the Nexus Hub at app.nexus-dev.codezerogroup.com. They have no database credentials, no SSH access, and no code repository access.

4.1 What App Owners Can Do After NX-S18

ActionHowGate
Browse available apps in OrchestratorDynamic card grid from GET /apps/catalogNX-S18-WP2 delivers
Open a pipeline in the canvas editorSelect org → select pipeline → canvas loadsAlready delivered (NX-S17)
Add a node from the paletteToggle palette → drag node to canvasAlready delivered (NX-S17)
Connect nodes with edgesClick output pin → drag to input pinAlready delivered (NX-S17)
Configure a node's propertiesRight-click node → open property editor → fill fieldsNX-S18-WP4 delivers (6 priority nodes)
Save a pipelineToolbar save button → PUT /pipelines/{id}Already delivered (NX-S17)
Run a pipeline and see live progressRun button → SSE animation on canvasAlready delivered (NX-S17)
View run history and per-node logsRun log panel → history list → node detailAlready delivered (NX-S17)
Manage their own API keysApp Management → API Keys tab → create/revoke/rotateNX-S18-WP3 delivers
Register an MCP connectorApp Management → Connectors tab → add endpoint + authNX-S18-WP3 (basic); full connector registry NX-S20

4.2 What Requires a Platform Admin (App Owners Cannot Do)

ActionWhy RestrictedSprint
Provision a new tenant / appRequires DB migration + seed. Platform admin only until WP-5.6 self-service tenant provisioning API.NX-S20
Assign users to a tenantRBAC user assignment requires admin panel until user management UI is built.NX-S20
Publish an app to the catalogApp versioning and publishing (WP-5.5) not yet implemented.Post NX-S20
Configure external credentials (Twilio, Anthropic)Secrets stored in AWS Secrets Manager, accessible via admin panel or IaC only.Post NX-S20

5. Sprint Plan

NX-S18 Self-Service Foundation Planned
Objective — Eliminate hardcoded data from SPAs; give app owners API key management; complete node property editor for 6 priority node types. Gate — Gate 11 must still PASS after all changes. Additional: GET /apps/catalog returns HTTP 200 with correct schema; no JavaScript USE_CASES constant in WORMWOOD_APP.html; API keys CRUD functional in APP_MGMT.html.
NX-S18-WP1
App Catalog: DB migration + API route
Implement O6 milestone (NEXUS_ROADMAP.md Section 9) in full. Alembic migration creates app_catalog, app_component, and app_action tables per the schema in NEXUS_LLD.md Section 6. New FastAPI route GET /apps/catalog returns all apps with their components, versions, actions, and connection topology. Seed script populates 5 active use cases (ARC, Nesto, EDR, ENDO, AER) in app_catalog.
  • Alembic migration runs clean (exit 0) against both SQLite dev and PostgreSQL staging
  • GET /apps/catalog returns 200 with schema: [{slug, display_name, components[], actions[], connections[]}]
  • 5 use-case rows in app_catalog after seed
  • Migration is reversible (downgrade to previous head, tables drop cleanly)
Deps: NEXUS_LLD.md Section 4.1 + Section 6 (full spec). NEXUS_ROADMAP.md Section 9 (O6 scope). O6-WP1..3
NX-S18-WP2
Eliminate USE_CASES hardcoded array in WORMWOOD_APP.html
Replace the var USE_CASES = [...] JavaScript constant in WORMWOOD_APP.html (line ~942) with a fetch(engineUrl + '/apps/catalog') call. The card rendering function renderCards() is rewritten to consume the API response. Gate 11 Section 11 (Orchestrator SPA) must still PASS. GAP-12
  • grep -c "USE_CASES" docs/WORMWOOD_APP.html returns 0
  • Orchestrator card grid shows the 5 seeded apps from the database
  • Adding a new row to app_catalog makes it appear in the Orchestrator without code changes
  • Gate 11 Section 11 PASS (all Orchestrator scenarios)
Deps: NX-S18-WP1 (API must exist first). O6-WP4
NX-S18-WP3
API Key Management + Connector Registration UI (APP_MGMT.html)
Add two new tabs to APP_MGMT.html: API Keys and Connectors.

API Keys tab: Lists all API keys for the current org (masked, last-used, created dates). Create new key (generates UUID, copies to clipboard once). Revoke key (with confirmation). Rename key (display label). Backed by the existing core/api_key_store.py (248 lines, Production) via new routes in routes_orgs.py: GET /apps/{slug}/api-keys, POST /apps/{slug}/api-keys, DELETE /apps/{slug}/api-keys/{key_id}.

Connectors tab: Register an external connector endpoint (name, URL, auth type, auth value). Used by HttpForward and WebhookTrigger nodes to reference named connectors instead of hardcoded URLs. Backed by a new connector table (id, org_slug, name, url, auth_type, auth_value_encrypted). CRUD: GET /apps/{slug}/connectors, POST /apps/{slug}/connectors, DELETE /apps/{slug}/connectors/{id}. Auth values encrypted at rest using Fernet (symmetric key stored in Secrets Manager on AWS, env var locally).
  • API Keys tab renders in APP_MGMT.html with list, create, revoke, rename
  • Creating a key returns a UUID displayed once; subsequent views show masked value
  • Revoking a key makes subsequent API calls with that key return 401
  • Connectors tab renders with list, add, delete
  • Connector auth values are not returned in GET response (masked or omitted)
  • Gate 11 Section 8 (App Management) PASS after changes
Deps: core/api_key_store.py (exists, Production). New: connector table migration + routes. Fernet key via env var NEXUS_ENCRYPT_KEY.
NX-S18-WP4
Per-node property schemas for 6 priority nodes
The _open(pid, nid, nd) property editor shell exists in WORMWOOD_APP.html but renders a generic form for all node types. Define JSON schemas for the 6 most-used nodes and register them in the editor's node-type dispatch table. GAP-11

Priority nodes: HttpForward (url, method, headers, timeout_seconds, auth_type, auth_value), FormNode (schema_ref, rbac_role, style_ref, submit_label), AiTransform (provider, model, prompt_template, max_tokens), FieldMapper (mappings table: source_field / target_field / transform / drop), StoreNode (entity_class, deltaPrism_config, mode: create/update/upsert), IngestNode (source_type, source_config, field_map).

Each schema registers in a NODE_SCHEMAS map keyed by node type name. The _open() function reads NODE_SCHEMAS[nd.type] and renders typed fields: text input, dropdown (enum), URL input, integer, toggle (boolean), key-value table.
  • Opening property editor for HttpForward shows url/method/headers/timeout/auth fields
  • Opening property editor for FormNode shows schema_ref/rbac_role/style_ref/submit_label
  • Opening property editor for AiTransform shows provider dropdown/model/prompt template/max_tokens
  • Opening property editor for FieldMapper shows a mappings table (add row, delete row)
  • Opening property editor for StoreNode shows entity_class/deltaPrism_config/mode dropdown
  • Opening property editor for IngestNode shows source_type dropdown/source_config/field_map
  • Saving a pipeline after configuring node properties persists the config in the engine DB
  • Unknown node types fall back to the existing generic form (no regression)
Deps: _open() framework in WORMWOOD_APP.html (exists). Node type definitions in wormwood/schema/node_registry.py (1130 lines) as reference for field names.
NX-S19 AWS Infrastructure Deployed
Objective — Stand up the full AWS environment. Engine accessible at api.nexus-dev.codezerogroup.com. App owners can reach the platform from a browser with no local dependencies. Gate — Engine health endpoint returns HTTP 200 from public URL (https://api.nexus-dev.codezerogroup.com/health). Gate 11 UAT suite runs against localhost (dev) only — not against the live AWS endpoint. RESOLVED (2026-05-09): WP5 executed. SPA deployed to nexus-nsd-packages S3 bucket (see ISSUE-072 for naming deviation). ALB host-routing rule (priority 30) active: app.nexus-dev.codezerogroup.com → 302 → S3 HTTPS endpoint. scripts/smoke_test_aws.py exits 0 — all 3 acceptance criteria pass. Sprint badge corrected to Deployed.
NX-S19-WP1
VPC + Network + Security Groups (Terraform)
Create Terraform module infra/modules/network. VPC with CIDR 10.0.0.0/16. Two availability zones. Public subnets (10.0.1.0/24, 10.0.2.0/24) for ALB. Private subnets (10.0.11.0/24, 10.0.12.0/24) for ECS and RDS. Internet Gateway, NAT Gateways (one per AZ), route tables. Security groups per Section 3.1. Terraform state in S3 bucket nexus-tf-state with DynamoDB lock.
  • terraform plan exits 0 with no unexpected changes after apply
  • VPC and all subnets visible in AWS Console
  • Security group rules match Section 3.1 specification exactly
  • terraform destroy removes all resources cleanly
Deps: AWS account with provisioner IAM role. No dependency on NX-S18.
NX-S19-WP2
RDS PostgreSQL + Alembic Migration
RDS PostgreSQL 15 on db.t3.medium, multi-AZ, in private subnets. DB credentials auto-generated and stored in AWS Secrets Manager (nexus/prod/db). Alembic is already configured in the engine repo — update DATABASE_URL to read from Secrets Manager at runtime. Run all existing migrations against the new RDS instance via a one-off ECS task at deploy time. Include the NX-S18-WP1 app_catalog migration.
  • RDS instance is reachable from ECS task SG on port 5432 only
  • All existing Alembic migrations apply cleanly (exit 0)
  • NX-S18-WP1 migration applies cleanly (5 rows in app_catalog after seed)
  • Engine connects to RDS on startup (GET /health returns 200 with db_status: ok)
  • RDS is not reachable from the public internet
Deps: NX-S19-WP1 (VPC + SGs). NX-S18-WP1 (app_catalog migration).
NX-S19-WP3
ECS Fargate Task Definitions + ECR
Dockerfiles for nexus/engine and nexus/admin. Both already have requirements.txt and run as Python processes. ECR repositories created via Terraform. ECS cluster, two services (nexus-engine-svc, nexus-admin-svc). Task definitions read DB credentials and API key from Secrets Manager via task IAM role (no env vars in task def). Engine task: 1 vCPU / 2GB RAM, min 1 / max 4 replicas. Admin task: 0.5 vCPU / 1GB RAM, min 1 / max 1 replica. Health check: GET /health every 30s, unhealthy threshold 3.
  • Both Docker images build cleanly (docker build exits 0)
  • Images push to ECR successfully
  • ECS services reach RUNNING state (0 stopped tasks)
  • GET /health returns 200 from within the VPC (ECS exec or bastion)
  • No secrets in task definition environment variables or Docker images
Deps: NX-S19-WP1 (VPC). NX-S19-WP2 (RDS + Secrets Manager).
NX-S19-WP4
ALB + HTTPS + DNS
Application Load Balancer in public subnets. ACM certificate for *.nexus-dev.codezerogroup.com (DNS validation via Route 53). Listener on port 443, redirect port 80 to 443. Target groups: engine (port 8010, health /health), admin (port 8011, health /health). Listener rules: /api/* → engine TG, /admin/* → admin TG, default → S3 static bucket (SPA). Route 53 A record api.nexus-dev.codezerogroup.com aliased to ALB DNS name.
  • curl https://api.nexus-dev.codezerogroup.com/health returns HTTP 200 (from public internet)
  • HTTP 80 redirects to HTTPS 443 (curl -I shows 301)
  • ACM certificate is ISSUED and shows as valid in browser
  • Admin endpoint is not reachable from public internet (returns 403 or connection refused)
Deps: NX-S19-WP1 (VPC). NX-S19-WP3 (ECS services running). Route 53 hosted zone for codezerogroup.com.
NX-S19-WP5
S3 Static Hosting for Nexus SPAs
EXECUTED — 2026-05-09: SPA deployed to nexus-nsd-packages S3 bucket (static website hosting enabled, public read). ALB host-routing rule created (priority 30, host-header: app.nexus-dev.codezerogroup.com → HTTPS redirect to S3 REST endpoint). Bootstrap script injected into ui/index.html: sets ww_base_url to https://api.nexus-dev.codezerogroup.com on first load. scripts/smoke_test_aws.py exits 0. Naming deviation documented in ISSUE-072.
S3 bucket nexus-static with static website hosting enabled. ALB host-based routing rule: requests with Host: app.nexus-dev.codezerogroup.com forwarded to S3 static bucket. SPA ww_base_url localStorage default updated from localhost:8010 to https://api.nexus-dev.codezerogroup.com via substitution in ui/index.html before S3 sync. CI pipeline syncs ui/ to the bucket on each merge to main. S3 bucket for NSD packages (nexus-nsd-packages) created with versioning enabled, private ACL, lifecycle rule retaining last 10 versions.
  • https://app.nexus-dev.codezerogroup.com serves Nexus Hub SPA (HTTP 200, body contains ww_base_url, NOT Wormwood Engine Swagger signature)
  • https://app.nexus-dev.codezerogroup.com and https://api.nexus-dev.codezerogroup.com return different content (confirms ALB host-routing is active)
  • SPA default engine URL is https://api.nexus-dev.codezerogroup.com (not localhost)
  • CI sync runs on merge and updates S3 within 2 minutes
  • nexus-nsd-packages bucket exists, versioning enabled, not publicly readable
  • scripts/smoke_test_aws.py exits 0 (all three checks pass)
Deps: NX-S19-WP4 (ALB). CI pipeline setup.
NX-S19-WP6
CI/CD Pipeline
GitHub Actions workflow (or AWS CodePipeline if preferred). On push to main: run full test suite (pytest), build Docker images, push to ECR, run Alembic migrations via ECS task, update ECS service, sync docs to S3. On PR: run tests only. Fail fast: if any test fails or Docker build fails, deployment does not proceed. Deployment secrets (AWS credentials, ECR URLs) stored in GitHub Actions secrets or CodePipeline IAM role.
  • Push to main triggers pipeline automatically
  • Pipeline fails if any of the 2,712 tests fail
  • Pipeline fails if Docker build fails
  • Successful run deploys to ECS and syncs S3 within 10 minutes
  • Pipeline run log is visible in GitHub Actions / CodePipeline console
Deps: NX-S19-WP3..WP5 (targets must exist). GitHub repo push access.
NX-S20 RBAC + Tenant Self-Provisioning Planned
Objective — Implement multi-tenant RBAC (WP-5.3 + WP-5.6) so platform admins can provision new tenants via API and app owners manage their own users through the interface. Gate — New tenant provisioned via API; Nesto roles (hr_admin / reviewer / auditor / submitter) enforced on form fields; data isolation verified (tenant A cannot read tenant B pipeline data).
NX-S20-WP1
Tenant Table + DB Migration
Alembic migration adds tenant table per NEXUS_LLD.md Section 7.2 schema. app_catalog table gains tenant_id foreign key. All existing org data migrated to a default uv-internal tenant. Tenant provisioning API: POST /tenants (platform admin only), GET /tenants/{slug}, DELETE /tenants/{slug}.
  • Migration applies cleanly to production RDS
  • Existing data migrated to uv-internal tenant with no data loss
  • POST /tenants creates a new tenant and returns the tenant slug and a provisioned admin API key
  • New tenant has empty app_catalog (no apps from other tenants visible)
Deps: NX-S19-WP2 (RDS). NEXUS_LLD.md Section 7.2. WP-5.6
NX-S20-WP2
RBAC Role Table + Scoped Pipeline Queries
New tables: role (id, tenant_id, name, permissions JSON), user_role (user_id, role_id, app_slug). All pipeline queries in routes_pipelines.py gain a tenant_id filter. API keys are now tenant-scoped: a key for Tenant A cannot list or run Tenant B pipelines. Role hierarchy from NEXUS_LLD.md Section 8.1: platform_admin / tenant_admin / app_admin / app_user / app_viewer.
  • API key for Tenant A returns 403 on GET /pipelines?org_slug=tenantB-app
  • Tenant A pipelines do not appear in Tenant B app catalog
  • platform_admin key can access all tenants
  • Existing tests still pass (uv-internal tenant scoping applied correctly)
Deps: NX-S20-WP1. NEXUS_LLD.md Section 8. WP-5.3
NX-S20-WP3
Nesto RBAC: Field-Level Role Enforcement
Implement the four Nesto roles (nesto_hr_admin, nesto_reviewer, nesto_auditor, nesto_submitter) from NEXUS_LLD.md Section 8.2. FormNode property schema gains a rbac_visibility field map: per-field, per-role: visible / read_only / hidden. The engine enforces this at the API level (hidden fields stripped from response). ChameleonV2 enforces this at the form level (read_only = non-editable, hidden = not rendered). ApprovalGate node gains a role_required enforcement: only users with nesto_reviewer or nesto_hr_admin can approve.
  • nesto_submitter cannot see the approval_result field
  • nesto_auditor sees all fields as read-only
  • nesto_reviewer can approve/reject at the ApprovalGate node
  • nesto_submitter attempting to POST to the ApprovalGate resume endpoint returns 403
  • Gate 11 Nesto scenarios PASS
Deps: NX-S20-WP2. FormNode property schema (NX-S18-WP4 delivered the schema framework).
NX-S20-WP4
User Management UI in APP_MGMT.html
Add a Users tab to APP_MGMT.html (joining API Keys and Connectors tabs from NX-S18-WP3). App admins can: invite a user (by email, generates a time-limited invite token), assign roles, remove users from the app. Tenant admins can: see all users across apps within their tenant, promote to app_admin. Backed by: POST /apps/{slug}/users/invite, PUT /apps/{slug}/users/{user_id}/role, DELETE /apps/{slug}/users/{user_id}.
  • Users tab renders in APP_MGMT.html with user list and role badges
  • Invite generates a token (emailed or copied); accepting invite creates the user record
  • Role change takes effect on next API call from that user
  • Removing a user revokes all their API keys for that app
Deps: NX-S20-WP2. NX-S18-WP3 (APP_MGMT tab framework).

6. Open Items and Risks

IDItemSprintRisk LevelMitigation
RISK-01 SSE telemetry stream compatibility with ALB timeout NX-S19 Medium ALB idle timeout default is 60s. SSE connections are long-lived. Set ALB idle timeout to 3600s for the engine target group. Alternatively, configure SSE to send keepalive comments every 30s (already supported in routes_pipelines.py).
RISK-02 ChameleonV2 BDT Phase 1 (GAP-02) not in NX-S18..S20 scope Post S20 Medium FormNode property editor in NX-S18-WP4 uses the demo form layer (plain HTML/JS, authorised by NEXUS_DEMO_SPEC.html REM-01..08) until ChameleonV2 Phase 1 (M-NEXUS-CV-2/CV-3) delivers. This is an accepted scoped exception per Tier 4 hierarchy rules. App owners can still configure and run pipelines; the production form renderer is a separate sprint.
RISK-03 Lambda handler scaffold is 19 lines — cold start on SSE Post S20 Low Fargate is the initial compute target (NX-S19). Lambda migration is a Phase 4 item. The scaffold exists; no action required until Phase 4.
RISK-04 Connector credential encryption key management NX-S18 Medium For NX-S18 (local dev), Fernet key via env var NEXUS_ENCRYPT_KEY. For NX-S19 (AWS), key stored in Secrets Manager and accessed via ECS task IAM role. Do not hardcode the key or commit it to the repository.
RISK-05 NANO/PICO rule wiring (GAP-13) deferred Post S20 Low Rule references can be set in the property editor (setRuleRef exists). Full inline rule editing via PICO level is post-S20. App owners can view rule IDs in the editor and use the Rule Registry HTML for reference.

7. Document Chain Cross-References

This DocumentReferencesRelationship
ADP-1.0 Section 2NEXUS_COMPONENT_STATUS.html Section 8.1Reads current state from. Do not duplicate; reference only.
ADP-1.0 Section 2 (gaps)NEXUS_CAPABILITY_GAP_ANALYSIS.md GAP-11, GAP-12, GAP-13Sprint WPs close these gaps. Update gap status on sprint completion.
ADP-1.0 Section 5 NX-S18-WP1/2NEXUS_ROADMAP.md Section 9 (O6 milestone)O6 scope fully implemented by WP1+WP2. Mark O6 SCHEDULED: NX-S18.
ADP-1.0 Section 5 NX-S18-WP3/4NEXUS_LLD.md Section 3.3.1, Section 13WP3 adds new routes per LLD design. WP4 clears LLD Section 13 USE_CASES row.
ADP-1.0 Section 3NEXUS_DEPLOYMENT_MATRIX.html Section 4 (Cloud-Native SaaS)Target stack is the Cloud-Native SaaS combo. ADP-1.0 is the concrete instantiation.
ADP-1.0 Section 5 NX-S20NEXUS_LLD.md Section 7 (Multi-Tenancy), Section 8 (RBAC)WP1-WP4 implement the LLD data models exactly. No divergence permitted.
ADP-1.0 Section 6 RISK-02NEXUS_DEMO_SPEC.html REM-01..08, NEXUS_DOC_HIERARCHY.html Tier 4Demo form layer in NX-S18 property editor is a Tier 4-authorised exception. References the same authorisation as WORMWOOD_APP.html demo panels.

8. Version History

VersionDateChanges
ADP-1.02026-05-08Initial document. Three-sprint plan (NX-S18..NX-S20). AWS target architecture. Self-service model. 5 risk items. Cross-reference table. Authority: Tier 3.