Skip to main content

ISB Frontend

Last Updated: 2026-03-02 Source: co-cddo/innovation-sandbox-on-aws Captured SHA: cf75b87

Executive Summary

The Innovation Sandbox frontend is a React 18 single-page application built with TypeScript, Vite 7.2, and the AWS Cloudscape Design System. It provides a role-based interface for end users to request sandbox accounts, for managers to approve requests, and for admins to manage the account pool and configuration. The frontend is built at CDK synth time, deployed to S3, and served through a CloudFront distribution that also proxies API requests to the API Gateway backend. Authentication uses SAML 2.0 SSO via IAM Identity Center, with JWT tokens for subsequent API calls.

Architecture Overview


Technology Stack

LayerTechnologyVersionPurpose
FrameworkReact18.3.1UI component library
LanguageTypeScript5.5.4Type-safe development
Build ToolVite7.2.2Dev server and production bundler
UI LibraryAWS Cloudscape Design System3.0.957AWS-native component library
Data FetchingTanStack Query (React Query)5.74.4Server state management with caching
RoutingReact Router6.30.1Client-side SPA routing
Notificationsreact-toastify11.0.2Toast notification system
Markdownreact-markdown9.0.3Help page rendering
Animationframer-motion11.3.28Page transitions
Iconsreact-icons5.3.0Icon library
Datemoment2.30.1Date formatting
StylingSCSSvia sass 1.77.8Custom styles
TestingVitest + Testing Library--Unit and component testing
MockingMSW2.3.1API mocking for tests

Source: source/frontend/package.json


Application Structure

Folder Layout

source/frontend/
public/
markdown/ # Help documentation (rendered with react-markdown)
home.md, leases.md, request.md, approvals.md,
accounts.md, lease-templates.md, settings.md
favicon.ico, logo192.png, logo512.png, manifest.json
src/
assets/
images/logo.png
styles/
app.scss # Application-wide styles
base.scss # CSS reset and base
util.scss # Utility classes
components/ # Shared/reusable components
AccountsSummary/ # Pool status pie chart + table
Animate/ # Page transition wrapper
AppContext/ # Global app state provider
AppLayout/ # Main layout shell with navigation
Authenticator/ # Auth check wrapper
BudgetProgressBar/ # Budget visualization
Form/ # Form context and helpers
FullPageLoader/ # Loading spinner
Loader/ # Inline loader
Markdown/ # Markdown renderer component
ThresholdSettings/ # Budget/duration threshold editor
Toast/ # Toast notification helper
domains/ # Feature-based module organization
home/
components/
AccountsPanel.tsx # Pool capacity summary
ApprovalsPanel.tsx # Pending approvals count
LeasePanel.tsx # Lease statistics
MyLeases.tsx # User's active leases
pages/Home.tsx # Dashboard page
leases/
components/ # Lease-specific UI components
pages/
ListLeases.tsx # Lease table with filters
RequestLease.tsx # New lease request form
AssignLease.tsx # Manager assigns to user
UpdateLease.tsx # Edit/extend lease
ListApprovals.tsx # Pending approval queue
ApprovalDetails.tsx # Review and approve/deny
service.ts # API calls for leases
hooks.ts # React Query hooks
helpers.ts # Utility functions
types.ts # TypeScript interfaces
leaseTemplates/
components/
BasicDetailsForm.tsx # Name, description, visibility
BudgetForm.tsx # Budget and thresholds
DurationForm.tsx # Duration and thresholds
CostReportForm.tsx # Cost reporting group
pages/
ListLeaseTemplates.tsx # Template catalog
AddLeaseTemplate.tsx # Create new template
UpdateLeaseTemplate.tsx # Edit existing template
formFields/ # Reusable form field components
accounts/
pages/
ListAccounts.tsx # Pool account inventory
AddAccounts.tsx # Register new accounts
service.ts # API calls for accounts
settings/
pages/Settings.tsx # Global configuration editor
helpers/
AuthService.ts # SAML SSO login/logout helpers
hooks/
useModal.tsx # Modal state management
useUser.tsx # Current user context hook
lib/
api.ts # Axios-based API client
App.tsx # Root component with routes
main.tsx # Entry point (React.createRoot)
index.html # HTML template
package.json
vite.config.ts
tsconfig.json

Source: source/frontend/src/


Routing and Pages

Route Configuration

All routes are defined in App.tsx:

const routes = [
{ path: "/", Element: Home },
{ path: "/request", Element: RequestLease },
{ path: "/assign", Element: AssignLease },
{ path: "/settings", Element: Settings },
{ path: "/lease_templates", Element: ListLeaseTemplates },
{ path: "/lease_templates/new", Element: AddLeaseTemplate },
{ path: "/lease_templates/edit/:uuid", Element: UpdateLeaseTemplate },
{ path: "/accounts", Element: ListAccounts },
{ path: "/accounts/new", Element: AddAccounts },
{ path: "/approvals", Element: ListApprovals },
{ path: "/approvals/:leaseId", Element: ApprovalDetails },
{ path: "/leases", Element: ListLeases },
{ path: "/leases/edit/:leaseId", Element: UpdateLease },
];

Role-Based Access

Routes are filtered in the navigation sidebar based on user roles:

RouteUserManagerAdminDescription
/ (Home)YesYesYesDashboard with lease stats and panels
/requestYesYesYesRequest a new sandbox lease
/leasesYesYesYesView own leases (all leases for Manager/Admin)
/leases/edit/:leaseIdYesYesYesUpdate/extend a lease
/assign--YesYesCreate lease on behalf of another user
/approvals--YesYesView and action pending approval queue
/approvals/:leaseId--YesYesDetailed approval review
/lease_templatesYesYesYesBrowse lease templates (create/edit for Admin/Manager)
/lease_templates/new--YesYesCreate new template
/lease_templates/edit/:uuid--YesYesEdit existing template
/accounts----YesPool account management
/accounts/new----YesRegister new accounts
/settings----YesGlobal configuration (AppConfig)

Source: source/frontend/src/App.tsx, source/lambdas/api/authorizer/src/authorization-map.ts


Authentication Flow

SAML SSO with IAM Identity Center

The Authenticator component (source/frontend/src/components/Authenticator/index.tsx) wraps the entire application. It uses the useUser hook to check for a valid JWT token. If no user is found, it calls AuthService.login() which redirects the browser to the IAM Identity Center sign-in URL (configured in AppConfig's auth.idpSignInUrl).

The JWT contains:

  • email: User's email address
  • Roles derived from IDC group membership (Admin, Manager, User)
  • Expiry based on auth.sessionDurationInMinutes (default: 60 minutes)

The JWT signing secret is stored in Secrets Manager and rotated every 30 days.

Source: source/frontend/src/components/Authenticator/index.tsx, source/lambdas/api/sso-handler/


State Management

TanStack Query Configuration

const queryClient = new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
refetchOnMount: false,
retry: false,
},
},
});

This conservative configuration avoids excessive API calls. Data is cached and only refreshed on explicit user action or mutation invalidation.

Cache key patterns:

  • ['leases', filters] -- Lease list
  • ['lease', leaseId] -- Single lease
  • ['leaseTemplates'] -- Template list
  • ['leaseTemplate', uuid] -- Single template
  • ['accounts'] -- Account list
  • ['configurations'] -- AppConfig settings

API Client

The frontend makes API calls to /api/* which CloudFront proxies to API Gateway. Each request includes the JWT token in the Authorization header.

The service layer pattern uses separate service.ts files per domain:

  • source/frontend/src/domains/leases/service.ts
  • source/frontend/src/domains/accounts/service.ts
  • etc.

React Query hooks in hooks.ts wrap service calls with caching, invalidation, and loading state management.


Key Pages

Home Dashboard

Route: / Component: domains/home/pages/Home.tsx

The dashboard displays four panels:

  • MyLeases: Current user's active leases with status badges
  • LeasePanel: Quick statistics (active, pending, expired counts)
  • AccountsPanel: Pool capacity visualization (available vs. leased vs. quarantine)
  • ApprovalsPanel: Pending approval count (Manager/Admin only)

Request Lease

Route: /request Component: domains/leases/pages/RequestLease.tsx

Form fields:

  1. Lease Template (dropdown): Fetches from /leaseTemplates (PUBLIC visibility for Users, all for Admins/Managers)
  2. Comments (textarea, optional): Justification for the request
  3. Terms of Service: Displayed from AppConfig termsOfService, must be accepted

Submission triggers POST /leases with the selected template UUID and comments.

Assign Lease

Route: /assign Component: domains/leases/pages/AssignLease.tsx Access: Manager and Admin only

Allows creating a lease on behalf of another user. Additional field for target user email. Uses POST /leases with the userEmail field set to the target.

List Leases

Route: /leases Component: domains/leases/pages/ListLeases.tsx

Cloudscape Table with:

  • Filtering by status, template, owner
  • Sorting by creation date, expiration date
  • Pagination
  • Actions: View, Edit, Terminate, Freeze/Unfreeze

Approval Queue

Route: /approvals Component: domains/leases/pages/ListApprovals.tsx Access: Manager and Admin only

Lists all PendingApproval leases with approve/deny quick actions.

Approval Details

Route: /approvals/:leaseId Component: domains/leases/pages/ApprovalDetails.tsx Access: Manager and Admin only

Displays full lease request details (requester, template, budget, duration, comments) with Approve and Deny buttons. Deny requires a reason.

Lease Templates

Route: /lease_templates Component: domains/leaseTemplates/pages/ListLeaseTemplates.tsx

Catalog of available lease templates. Admins and Managers can create/edit/delete templates.

Template Editor

Route: /lease_templates/new or /lease_templates/edit/:uuid Components: AddLeaseTemplate.tsx, UpdateLeaseTemplate.tsx

Multi-section form:

  1. BasicDetailsForm: Name, description, visibility (PUBLIC/PRIVATE), requires approval toggle
  2. BudgetForm: Max spend, budget thresholds with actions (ALERT/FREEZE_ACCOUNT)
  3. DurationForm: Duration in hours, duration thresholds with actions
  4. CostReportForm: Cost reporting group assignment

Account Pool

Route: /accounts Component: domains/accounts/pages/ListAccounts.tsx Access: Admin only

Displays all pool accounts with status, lease association, and actions (retry cleanup, eject).

Add Accounts

Route: /accounts/new Component: domains/accounts/pages/AddAccounts.tsx Access: Admin only

Displays unregistered accounts found in sandbox OUs (via GET /accounts/unregistered) and allows bulk registration.

Settings

Route: /settings Component: domains/settings/pages/Settings.tsx Access: Admin only

Configuration editor for AppConfig profiles:

  • Global settings (maintenance mode, lease limits, auth, notifications)
  • Nuke configuration (protected resources, settings)
  • Reporting configuration

Hosting Infrastructure

S3 Bucket

  • KMS-encrypted with customer-managed key
  • Versioning enabled
  • Public access blocked (CloudFront OAC only)
  • Deletion protection in production mode

CloudFront Distribution

SettingValue
Default originS3 bucket via Origin Access Control (OAC)
API originAPI Gateway REST API (/api/*)
Viewer protocolHTTPS redirect
Price classAll edge locations
HTTP versionHTTP/2
Minimum TLSTLS 1.2 (2019 policy)
IPv6Disabled
Default root objectindex.html

Cache behaviors:

PathOriginCacheFunction
Default (/*)S3CACHING_OPTIMIZEDIsbS3OriginPathRedirectCloudFrontFunction (SPA routing)
/api/*API GatewayCACHING_DISABLEDIsbPathRewriteCloudFrontFunction (strip /api prefix)

CloudFront Functions:

  1. Path Redirect (IsbS3OriginPathRedirectCloudFrontFunction): Rewrites requests without a file extension to /index.html, enabling client-side routing (e.g., /leases serves index.html, not a 404).

  2. API Path Rewrite (IsbPathRewriteCloudFrontFunction): Strips the /api prefix before forwarding to API Gateway (e.g., /api/leases becomes /leases).

Security Headers

The CloudFront Response Headers Policy enforces:

HeaderValue
Content-Security-Policydefault-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self' data:; connect-src 'self'; manifest-src 'self'; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; upgrade-insecure-requests;
Strict-Transport-Securitymax-age=46656000; includeSubDomains (540 days)
X-Content-Type-Optionsnosniff
X-Frame-OptionsDENY
Referrer-Policyno-referrer
Cache-Controlno-store, no-cache

Source: source/infrastructure/lib/components/cloudfront/cloudfront-ui-api.ts


Build and Deployment

Build Process

The frontend is built at CDK synth time by the buildFrontend() function in the CloudFront construct:

  1. npm run build is executed in source/frontend/
  2. TypeScript type checking (tsc --incremental --noEmit)
  3. Vite production build (vite build)
  4. Output to source/frontend/dist/
  5. CDK's BucketDeployment uploads dist/ to S3
  6. CloudFront invalidation triggered for /*

Vite Configuration

export default defineConfig({
resolve: {
alias: {
"@amzn/innovation-sandbox-frontend": path.resolve(__dirname, "./src"),
},
},
plugins: [react()],
build: {
chunkSizeWarningLimit: 3000,
},
});

The @amzn/innovation-sandbox-frontend alias maps to src/, enabling clean imports throughout the codebase.

Source: source/frontend/vite.config.ts


Cloudscape Design System Components

The frontend uses AWS Cloudscape Design System exclusively for UI components. Key components in use:

ComponentUsage
TableLease lists, account lists, template lists
Form, FormField, Input, Select, TextareaAll forms (request, template, settings)
Button, SpaceBetween, BoxLayouts and actions
Container, HeaderPage sections
StatusIndicatorLease and account status badges
ProgressBarBudget consumption visualization
FlashbarInline notification banners
ModalConfirmation dialogs
PaginationTable pagination
SideNavigationNavigation sidebar
TopNavigationApp header with user menu
PieChartAccount pool distribution
TabsSettings page sections

Additional library: @aws-northstar/ui (1.4.2) extends Cloudscape with higher-level components.


Component Hierarchy

The component hierarchy wraps every page in:

  1. QueryClientProvider: TanStack Query cache
  2. Authenticator: JWT check, SSO redirect if unauthenticated
  3. BrowserRouter: Client-side routing
  4. ModalProvider: Global modal state
  5. AppLayout: Cloudscape shell with side navigation and top bar

Testing

The frontend uses Vitest with Testing Library for unit and component tests:

  • Test runner: Vitest (vitest run --coverage)
  • DOM environment: jsdom
  • Component testing: @testing-library/react with @testing-library/user-event
  • API mocking: MSW (Mock Service Worker) for intercepting API calls

Tests are located alongside their source files or in dedicated test directories.

Source: source/frontend/package.json



Generated from source analysis. See 00-repo-inventory.md for full inventory.