AWS Backend Setup
Select this backend with npm run init:backend -- --provider aws. This first iteration assumes a static Observable Framework frontend backed by Cognito, API Gateway, Lambda, DynamoDB, S3, EventBridge, and SES. Authorization and storage should follow the product progression: projects first, optional team assignment second, optional account assignment third.
AWS can be the only cloud backend for a local workspace, or it can be connected alongside Azure. In both cases the application model remains provider-neutral: S3 stores object bytes and workspace envelopes, DynamoDB stores sync indexes and application records, and the coordinating node handles push/pull sync.
This page covers private AWS backend resources. Public AWS static-site publishing is covered in Frontend Deployment.
Cognito
Create one user pool for application users and map deployment-level groups into ID token claims:
application_super_admin: can create organizational accounts and inspect platform metadata.PlatformAdmin: can operate platform configuration.ProjectOwner: can create and manage project-level grants where allowed.
Do not rely on Cognito groups as the only authorization source. The API should normalize the Cognito identity into an application user, then compute project permissions from DynamoDB membership and grant records.
DynamoDB Tables
Use separate tables or a single-table design with clear item types:
USER#user_id: profile, workspace label, notification settings.ACCOUNT#account_id: account metadata, billing plan, data classification.ACCOUNT#account_id MEMBER#user_id: account role and permissions.TEAM#team_id: team scope, parent team, root administrator.TEAM#team_id MEMBER#user_id: team role and permissions.PROJECT#project_id: project metadata, private workspace state, and optional team or account assignment.PROJECT#project_id GRANT#grant_id: user, team, or account project grant.ARTIFACT#artifact_id: file/document artifact ownership, storage provider, S3 key, classification, tags, and related object ids.INVITATION#invitation_id: pending scoped invitations.
Recommended indexes:
GSI1PK = ACCOUNT#account_idfor account projects, members, and teams.GSI2PK = TEAM#team_idfor team membership and project grants.GSI3PK = USER#user_idfor user memberships, invitations, and preferences.GSI4PK = PROJECT#project_idfor grants and artifacts.
Project assignment changes should be explicit writes to the project item. Assigning a project to a team should copy the team's account scope when the team is account-scoped. Assigning a project directly to an account should clear team_id.
S3
Store raw and processed files under private prefixes:
accounts/{account_id}/projects/{project_id}/documents/{document_id}/raw/{filename}
accounts/{account_id}/projects/{project_id}/documents/{document_id}/processed/{artifact_name}.json
workspaces/{workspace_id}/projects/{project_id}/documents/{document_id}/raw/{filename}
Uploads should use short-lived presigned URLs returned by POST /api/uploads/presign from the project file manager or file repository. Lambda should create the artifact record before issuing the URL, then confirm object existence after upload.
Bootstrap Script
npm run init:backend -- --provider aws --environment dev --prefix workspace-management --region us-east-1
export AWS_REGION=us-east-1
export AWS_S3_BUCKET=workspace-management-dev-documents
export AWS_DYNAMODB_TABLE=workspace-management-dev
npm run setup:aws
Notifications
Use EventBridge for administrative events:
- account member added or failed
- team member added or failed
- project shared
- project access changed
- file artifact created
Notification routing should read per-user preferences before sending in-app or email alerts. Account owners and Super-admins are default recipients for account and team membership events.
Guardrails
Super-admin metadata access does not imply content access to restricted project files. File download and presigned upload APIs must require effective project permission, not just deployment role membership.