Skip to content

Commit 87a9a8a

Browse files
JiaDeclaude
andcommitted
docs: comprehensive README_ENTERPRISE.md accuracy update
- Seed Accounts: replaced fictional emp-ada/emp-wjd/emp-admin with actual 20 seed employees from seed_dynamodb.py + seed_roles.py (2 admin, 3 manager, 15 employee) - Sample Org: 13 departments (was 7), accurate skill/KB/channel counts - Environment Variables: split into .env (deploy input) and runtime (/etc/openclaw/env) sections, added ECS vars, matched .env.example - For AI Assistants: updated for 4-tier architecture, corrected verification steps to use actual employee IDs - Project Structure: added agent-container detail (12 files), exec-agent openclaw.json, auth-agent directory - What to Test: corrected employee names/tiers (Peter Wu not WJD/Ada) - Prerequisites: Bedrock model access is automatic, added ecs/efs perms - Router count: 16 → 17 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent cc125af commit 87a9a8a

1 file changed

Lines changed: 110 additions & 63 deletions

File tree

README_ENTERPRISE.md

Lines changed: 110 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -468,23 +468,25 @@ Zero IT friction. Employees self-service in 30 seconds. Admins see all connectio
468468
469469
---
470470

471-
**What you're deploying:** A multi-tenant enterprise AI platform — a gateway layer (Tenant Router + Admin Console) routes requests to isolated Firecracker microVMs via AWS Bedrock AgentCore. Two Docker images, two Runtimes (Standard + Executive), one DynamoDB table, one S3 bucket. Optional ECS Fargate always-on agents for scheduled tasks and direct IM.
471+
**What you're deploying:** A multi-tenant enterprise AI platform — a gateway layer (Tenant Router + Admin Console) routes requests to isolated Firecracker microVMs via AWS Bedrock AgentCore. One Docker image serves both AgentCore (serverless) and ECS Fargate (always-on). 4 AgentCore Runtimes (Standard/Restricted/Engineering/Executive), one DynamoDB table, one S3 bucket, one ECS cluster with 4 tier services.
472472

473-
**Run Docker builds on the gateway EC2, not the user's local machine.** After Step 1 creates the EC2, use SSM to build on it — the EC2 is ARM64 Graviton, has Docker pre-installed, and has fast internal network to ECR. Building ARM64 images locally via QEMU emulation is slow and error-prone. Use `enterprise/agent-container/build-on-ec2.sh` for the standard image; adapt the same pattern for exec-agent (Step 1.5).
473+
**Run Docker builds on the gateway EC2, not the user's local machine.** `deploy.sh` handles this automatically — packages source → S3 → EC2 builds via SSM (ARM64 Graviton). No local Docker required.
474474

475475
**Critical — these will silently break deployment if missed:**
476476

477-
1. **The `openclaw` npm package is pinned to `2026.3.24`** in `agent-container/Dockerfile` and `exec-agent/Dockerfile` — do not upgrade. Newer versions changed the Gateway response delivery mechanism and break IM channel integration. (The single-user EC2 template supports `2026.4.5+` but Enterprise remains on `2026.3.24`.)
478-
2. **Build both Docker images**`agent-container/` (standard) and `exec-agent/` (executive). Don't skip exec even if only standard agents are needed initially.
479-
3. **Docker build takes 10–15 min**`clawhub install` installs skills one by one. This is normal.
480-
4. **After `update-agent-runtime`**, poll until `status: READY` before testing.
481-
5. **DynamoDB is in `us-east-2` by default** (AgentCore is `us-east-1`). This is intentional — DynamoDB cross-region access is free and `us-east-2` avoids hitting AgentCore's region during heavy load.
477+
1. **OpenClaw is pinned to `2026.3.24`** in `agent-container/Dockerfile` and `exec-agent/Dockerfile` — do not upgrade. Newer versions changed Gateway response delivery and break IM channel integration. (The single-user EC2 template supports `2026.4.5+` but Enterprise remains on `2026.3.24`.)
478+
2. **Docker build takes 10–15 min**`clawhub install` installs skills one by one. This is normal.
479+
3. **After `update-agent-runtime`**, poll until `status: READY` before testing.
480+
4. **DynamoDB is in `us-east-2` by default** (AgentCore is `us-east-1`). This is intentional — DynamoDB cross-region access is free.
481+
5. **deploy.sh creates 4 Fargate tier services** with `desiredCount=0`. Admin activates per-employee always-on from Security Center UI.
482+
6. **All 20 seed employees share one `ADMIN_PASSWORD`** — each must change on first login. Roles are seeded separately by `seed_roles.py`.
482483

483484
**Verify it works** (after deployment):
484-
- Playground → Carol Zhang (Finance) → "run git status" → refused ✓
485-
- Playground → Ryan Park (SDE) → "run git status" → executes ✓
486-
- Playground → Rachel Li (Legal) → "what new tokens are going live?" → Guardrail blocks ✓
487-
- Playground → WJD (Executive) → same question → answers freely ✓
485+
- Login as `emp-jiade` (admin) → Dashboard shows 13 depts, 11 positions, 20 employees
486+
- Playground → Carol Zhang (Finance) → "run git status" → refused (Restricted tier)
487+
- Playground → Ryan Park (SDE) → "run git status" → executes (Engineering tier)
488+
- Portal → Carol Zhang → Chat → "Who are you?" → "Finance Analyst Agent at ACME Corp"
489+
- Security Center → 4 runtimes all READY
488490

489491
**If AgentCore returns 500:** check CloudWatch group `/aws/bedrock-agentcore/runtimes/<runtime-id>-DEFAULT` for `openclaw returned empty output` — wrong openclaw version. Rebuild with `openclaw@2026.3.24`.
490492

@@ -512,9 +514,9 @@ Zero IT friction. Employees self-service in 30 seconds. Admins see all connectio
512514
> **No local Docker required** — the agent container image is built on the gateway EC2 (ARM64 Graviton) via SSM.
513515
514516
**AWS requirements:**
515-
- Bedrock model access: Nova 2 Lite (default) + Anthropic Claude (exec tier + Admin Assistant)
517+
- Bedrock model access is automatic — no manual enablement required
516518
- Bedrock AgentCore available in: `us-east-1`, `us-west-2`
517-
- IAM permissions: `cloudformation:*`, `ec2:*`, `iam:*`, `ecr:*`, `s3:*`, `ssm:*`, `bedrock:*`, `dynamodb:*`
519+
- IAM permissions: `cloudformation:*`, `ec2:*`, `iam:*`, `ecr:*`, `s3:*`, `ssm:*`, `bedrock:*`, `dynamodb:*`, `ecs:*`, `efs:*`
518520
519521
### Step 1: Configure and Deploy
520522
@@ -765,8 +767,8 @@ Employees self-service pair via Portal → Connect IM (QR code). No admin approv
765767
## What to Test
766768

767769
### 1. SOUL Injection (core differentiator)
768-
Login as **Carol Zhang** (Finance) → Chat → "Who are you?" → **"ACME Corp Finance Analyst"**
769-
Login as **Ryan Park** (SDE) → Chat → "Who are you?" → **"ACME Corp Software Engineer"**
770+
Login as **Carol Zhang** (emp-carol, Finance) → Chat → "Who are you?" → **"ACME Corp Finance Analyst"**
771+
Login as **Ryan Park** (emp-ryan, SDE) → Chat → "Who are you?" → **"ACME Corp Software Engineer"**
770772
Same LLM. Completely different identities.
771773

772774
### 2. Digital Twin
@@ -777,15 +779,14 @@ Turn OFF → incognito tab gets 404 immediately
777779
### 3. Org Directory (Knowledge Base)
778780
Ask any agent: *"Who should I contact for a code review?"* or *"What does Marcus Bell do?"*
779781
→ Agent reads `kb-org-directory` (seeded into every position) and answers with the right person's name, role, IM channel, and agent capabilities
780-
→ Works out-of-box after running `seed_knowledge_docs.py` — no manual KB assignment needed
781782

782-
### 4. Permission Boundaries
783-
Carol Zhang: "Run git status" → **Refused** (Finance, no shell)
784-
Ryan Park: "Run git status" → **Executed** (SDE, has shell)
785-
WJD / Ada: Any command → **Executed** (Executive tier, zero restrictions, Sonnet 4.6)
783+
### 4. Permission Boundaries (4-tier)
784+
Carol Zhang (Restricted): "Run git status" → **Refused** (Finance, no shell)
785+
Ryan Park (Engineering): "Run git status" → **Executed** (SDE, has shell)
786+
Peter Wu (Executive): Any command → **Executed** (Executive tier, Sonnet 4.6)
786787

787788
### 5. Multi-Runtime
788-
Login as **Ada** or **WJD** → these route to the Executive AgentCore Runtime:
789+
Login as **Peter Wu** (emp-peter) or **JiaDe Wang** (emp-jiade) → these route to the Executive AgentCore Runtime:
789790
- Model: Claude Sonnet 4.6 (vs Nova 2 Lite for standard)
790791
- Tools: all unlocked
791792
- IAM: full S3, all Bedrock models, cross-dept DynamoDB
@@ -832,55 +833,89 @@ Knowledge Base → **Assignments tab** → all positions are pre-assigned these
832833

833834
To add a new KB: Admin Console → Knowledge Base → upload Markdown → Assignments tab → assign to positions → agents pick it up on next cold start.
834835

835-
## Demo Accounts
836-
837-
> **Executive accounts (Ada, WJD)** run on the Executive AgentCore Runtime with Claude Sonnet 4.6, zero tool restrictions, and a full-access IAM role.
838-
839-
| Employee ID | Name | Role | Runtime | What They Experience |
840-
|-------------|------|------|---------|---------------------|
841-
| **emp-ada** | **Ada** | **Executive** | **exec-agent · Sonnet 4.6** | **All tools · Full IAM · Feishu + Telegram 🔓** |
842-
| **emp-wjd** | **WJD** | **Executive** | **exec-agent · Sonnet 4.6** | **All tools · Full IAM · Feishu + Telegram 🔓** |
843-
| emp-jiade | JiaDe Wang | Admin | standard | Discord → SA Agent ✨ |
844-
| emp-chris | Chris Morgan | Admin | standard | DevOps Agent (shell + infra tools) |
845-
| emp-peter | Peter Wu | Manager | standard | Portal/Discord → Executive Agent ✨ |
846-
| emp-alex | Alex Rivera | Manager | standard | Product dept manager view |
847-
| emp-mike | Mike Johnson | Manager | standard | Sales dept manager · CRM tools |
848-
| emp-ryan | Ryan Park | Employee | standard | Slack/Discord → SDE Agent (shell/code) |
849-
| emp-carol | Carol Zhang | Employee | standard | Telegram → Finance Agent |
850-
| emp-david | David Park | Employee | standard | Slack → Finance Agent ✨ |
851-
| **emp-admin** | **Demo Admin** | **Employee** | **exec-agent** | **Unrestricted test account · All tools · install_skill** |
852-
853-
> 🔓 = No tool restrictions · ✨ = Cross-session memory via S3
836+
## Seed Accounts
837+
838+
> The seed data creates 20 employees across 11 positions. Roles are assigned by `seed_roles.py`: 2 admins, 3 managers, 15 employees. All share the initial `ADMIN_PASSWORD` and must change it on first login.
839+
840+
| Employee ID | Name | Role | Position | Dept | Runtime Tier | Channels |
841+
|-------------|------|------|----------|------|-------------|----------|
842+
| **emp-jiade** | **JiaDe Wang** | **admin** | Solutions Architect | Engineering | Executive | Discord, Slack |
843+
| **emp-chris** | **Chris Morgan** | **admin** | DevOps Engineer | Platform Team | Engineering | Slack, Telegram |
844+
| emp-alex | Alex Rivera | manager | Product Manager | Product | Standard | Slack |
845+
| emp-mike | Mike Johnson | manager | Account Executive | Enterprise Sales | Standard | WhatsApp, Slack |
846+
| emp-jenny | Jenny Liu | manager | HR Specialist | HR & Admin | Standard | Slack |
847+
| emp-peter | Peter Wu | employee | Executive | Engineering | Executive | Discord |
848+
| emp-ryan | Ryan Park | employee | Software Engineer | Backend Team | Engineering | Slack, Discord |
849+
| emp-carol | Carol Zhang | employee | Finance Analyst | Finance | Restricted | Slack, Telegram |
850+
| emp-rachel | Rachel Li | employee | Legal Counsel | Legal & Compliance | Restricted | Slack |
851+
| emp-emma | Emma Chen | employee | Customer Success Manager | Customer Success | Standard | Slack, WhatsApp |
852+
| emp-marcus | Marcus Bell | employee | Solutions Architect | Engineering | Executive | Slack, Telegram |
853+
| emp-sophie | Sophie Turner | employee | Software Engineer | Backend Team | Engineering | Slack |
854+
| emp-nathan | Nathan Brooks | employee | Software Engineer | Frontend Team | Engineering | Slack |
855+
| emp-lisa | Lisa Chen | employee | DevOps Engineer | Platform Team | Engineering | Slack |
856+
| emp-tony | Tony Reed | employee | QA Engineer | QA Team | Engineering | Slack |
857+
| emp-sarah | Sarah Kim | employee | Account Executive | Enterprise Sales | Standard | WhatsApp |
858+
| emp-tom | Tom Wilson | employee | Account Executive | SMB Sales | Standard | Slack |
859+
| emp-priya | Priya Patel | employee | Product Manager | Product | Standard | Slack, Discord |
860+
| emp-david | David Park | employee | Finance Analyst | Finance | Restricted | Slack |
861+
| emp-daniel | Daniel Kim | employee | Solutions Architect | Engineering | Executive | Slack |
862+
863+
**Runtime tier assignment** (via Security Center → Position → Runtime mapping):
864+
- **Executive**: Solutions Architect (pos-sa)
865+
- **Engineering**: Software Engineer (pos-sde), DevOps Engineer (pos-devops), QA Engineer (pos-qa)
866+
- **Restricted**: Finance Analyst (pos-fa), Legal Counsel (pos-legal)
867+
- **Standard**: Account Executive (pos-ae), Product Manager (pos-pm), HR Specialist (pos-hr), Customer Success Manager (pos-csm), Executive (pos-exec)
854868

855869
## Environment Variables
856870

857-
| Variable | Required | Description |
858-
|----------|----------|-------------|
859-
| `ADMIN_PASSWORD` | Yes | Initial password for all accounts. Employees must set a personal password on first login. Stored in SSM SecureString. |
860-
| `JWT_SECRET` | Yes | JWT signing key. Generate: `openssl rand -hex 32` |
861-
| `AWS_REGION` | Yes | Deployment region for EC2, SSM, ECR, AgentCore (default: `us-east-1`) |
862-
| `GATEWAY_INSTANCE_ID` | Yes | EC2 instance ID — required for always-on container start/stop via SSM. Set in `/etc/openclaw/env`. Falls back to IMDSv2 if not set. |
863-
| `PUBLIC_URL` | No | Base URL for Digital Twin links (default: `https://openclaw.awspsa.com`) — **set this** for correct twin URLs |
864-
| `AGENT_ECR_IMAGE` | No | ECR image URI for always-on containers. Auto-built from `$ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$STACK_NAME-multitenancy-agent:latest` if not set. |
865-
| `CONSOLE_PORT` | No | Admin Console port (default: `8099`) |
866-
| `TENANT_ROUTER_URL` | No | Tenant Router URL (default: `http://localhost:8090`) |
867-
| `DYNAMODB_TABLE` | No | Table name — **must equal STACK_NAME** (IAM policy scoped to `table/${StackName}`). Default: same as STACK_NAME |
868-
| `DYNAMODB_REGION` | No | DynamoDB region if different from `AWS_REGION` (default: `us-east-2`) |
871+
### .env (deploy.sh input)
872+
873+
| Variable | Required | Default | Description |
874+
|----------|----------|---------|-------------|
875+
| `STACK_NAME` | Yes | `openclaw-enterprise` | Names ALL AWS resources. Unique per account/region. |
876+
| `REGION` | Yes | `us-east-1` | AWS region (must have Bedrock + AgentCore: `us-east-1` or `us-west-2`) |
877+
| `ADMIN_PASSWORD` | Yes || Initial password for all accounts. Stored in SSM SecureString. Employees must change on first login. |
878+
| `JWT_SECRET` | No | auto-generated | JWT signing key. Auto-generated with `openssl rand -hex 32` if empty. |
879+
| `MODEL` | No | `global.amazon.nova-2-lite-v1:0` | Default Bedrock model ID for standard agents |
880+
| `INSTANCE_TYPE` | No | `c7g.large` | EC2 Graviton ARM instance type |
881+
| `KEY_PAIR` | No || EC2 key pair name for emergency SSH |
882+
| `EXISTING_VPC_ID` | No || Reuse existing VPC instead of creating new |
883+
| `EXISTING_SUBNET_ID` | No || Reuse existing subnet |
884+
| `CREATE_VPC_ENDPOINTS` | No | `false` | Add Bedrock/SSM VPC endpoints (~$22/mo) |
885+
| `DYNAMODB_TABLE` | No | same as STACK_NAME | Table name — **must equal STACK_NAME** (IAM policy scoped to `table/${StackName}`) |
886+
| `DYNAMODB_REGION` | No | `us-east-2` | DynamoDB region if different from `REGION` |
887+
| `WORKSPACE_BUCKET_NAME` | No | auto | S3 bucket name — set if multi-stack same account |
888+
| `SKIP_DOCKER_BUILD` | No | `false` | Skip Docker build step (use existing image) |
889+
| `SKIP_SEED` | No | `false` | Skip DynamoDB seeding |
890+
891+
### Runtime variables (written to /etc/openclaw/env by deploy.sh)
892+
893+
| Variable | Description |
894+
|----------|-------------|
895+
| `PUBLIC_URL` | Base URL for Digital Twin links — **set this** for correct twin URLs |
896+
| `GATEWAY_INSTANCE_ID` | EC2 instance ID for always-on container management. Falls back to IMDSv2. |
897+
| `CONSOLE_PORT` | Admin Console port (default: `8099`) |
898+
| `TENANT_ROUTER_URL` | Tenant Router URL (default: `http://localhost:8090`) |
899+
| `ECS_CLUSTER_NAME` | ECS cluster for Fargate always-on agents |
900+
| `ECS_TASK_DEFINITION` | Fargate task definition ARN |
901+
| `ECS_SUBNET_ID` | Subnet for Fargate tasks |
902+
| `ECS_TASK_SG_ID` | Security group for Fargate tasks |
869903

870904
## Sample Organization
871905

872906
| | Count | Details |
873907
|-|-------|---------|
874-
| Departments | 7 | Engineering, Sales, Finance, HR, Product, Legal, Executive |
908+
| Departments | 13 | 5 Engineering (Platform/Backend/Frontend/QA), 3 Sales (Enterprise/SMB), Product, Finance, HR, CS, Legal |
875909
| Positions | 11 | SA, SDE, DevOps, QA, AE, PM, FA, HR, CSM, Legal, Executive |
876-
| Employees | 20+ | Each with workspace files in S3 |
877-
| Agents | 20+ | Serverless (default) + always-on (admin toggle) |
910+
| Employees | 20 | 2 admin, 3 manager, 15 employee — each with workspace files in S3 |
911+
| Agents | 20 | 1:1 bound to employees, serverless (default) + always-on (admin toggle) |
878912
| Runtimes | 4 | Standard, Restricted, Engineering, Executive (per-tier model + IAM + guardrail) |
879-
| IM Channels | 4 | Telegram, Feishu, Discord, Portal |
880-
| Skills | 5+ | Role-scoped skill packages in S3 |
881-
| Knowledge Docs | 11 | Topic KBs + company-directory.md (org directory, auto-assigned to all positions) |
913+
| IM Channels | 4 | Slack (most employees), Discord, Telegram, WhatsApp |
914+
| Skills | 5 | S3-based skill packages (jina-reader, deep-research, etc.) |
915+
| Knowledge Docs | 11 | Topic KBs (org-directory, policies, onboarding, arch, runbooks, finance, HR) |
882916
| SOUL Templates | 12 | 1 global + 11 position-specific |
883-
| RBAC Roles | 3 | Admin, Manager, Employee |
917+
| RBAC Roles | 3 | Admin (2), Manager (3), Employee (15) |
918+
| Seed Scripts | 11 | seed_dynamodb, seed_roles, seed_settings, seed_knowledge, seed_skills, etc. |
884919

885920
## Cost Estimate
886921

@@ -964,7 +999,7 @@ enterprise/
964999
│ ├── auth.py # JWT auth + UserContext
9651000
│ ├── db.py # DynamoDB single-table + Digital Twin CRUD
9661001
│ ├── password.py # bcrypt password hashing
967-
│ ├── routers/ # 16 domain routers (130+ API endpoints)
1002+
│ ├── routers/ # 17 domain routers (130+ API endpoints)
9681003
│ │ ├── org.py agents.py bindings.py knowledge.py
9691004
│ │ ├── portal.py playground.py monitor.py audit.py
9701005
│ │ ├── usage.py settings.py security.py
@@ -973,12 +1008,24 @@ enterprise/
9731008
│ │ └── __init__.py
9741009
│ └── seed_*.py # Sample data scripts
9751010
├── agent-container/ # AgentCore Docker image (OpenClaw 2026.3.24)
976-
│ ├── server.py # Workspace assembly + twin/always-on detection
977-
│ ├── workspace_assembler.py # 3-layer SOUL merge + KB injection
1011+
│ ├── Dockerfile # Pinned openclaw@2026.3.24 + 4 skills
1012+
│ ├── server.py # HTTP server: workspace assembly + invocation + usage tracking
1013+
│ ├── entrypoint.sh # Container startup: SSM registration, IM auto-connect
1014+
│ ├── workspace_assembler.py # 3-layer SOUL merge + KB injection + identity
9781015
│ ├── permissions.py # SSM permission profiles (base_id extraction)
1016+
│ ├── skill_loader.py # DynamoDB role lookup → skill filtering
1017+
│ ├── identity.py # Employee identity injection
1018+
│ ├── memory.py # Per-turn memory checkpoint
1019+
│ ├── observability.py # CloudWatch metrics
1020+
│ ├── safety.py # Guardrail enforcement
1021+
│ ├── openclaw.json # Agent config (deny built-in cron/gateway)
9791022
│ └── skills/ # Enterprise skills (eventbridge-cron, etc.)
9801023
├── exec-agent/ # Executive tier Docker image
981-
│ └── Dockerfile # All skills pre-installed, Sonnet 4.6
1024+
│ ├── Dockerfile # Pinned openclaw@2026.3.24 + 20 skills, Sonnet 4.6
1025+
│ └── openclaw.json # Executive config (full tool permissions)
1026+
├── auth-agent/ # Permission/approval agent
1027+
│ ├── server.py # Approval workflow HTTP server
1028+
│ └── permission_request.py # Permission request handler
9821029
├── gateway/
9831030
│ ├── bedrock_proxy_h2.js # H2 Proxy (channel detection, pairing intercept)
9841031
│ └── tenant_router.py # 3-tier routing + always-on container support

0 commit comments

Comments
 (0)