Cutout Studio is a portrait-focused background removal app with a stricter beta launch posture than a typical anonymous image utility.
It ships with:
- a local CLI for single-image and directory batch processing
- a web product built with React, TypeScript, Express, and local ONNX-based person segmentation
- safety controls for verified GitHub sign-in, policy acceptance, moderation, audit logging, abuse reporting, and admin review
The intended beta flow is:
- User signs in with GitHub.
- The callback accepts only accounts with a verified GitHub email.
- The app creates or updates the user record in Postgres.
- The current acceptable-use version must be accepted.
- Turnstile runs when configured.
- Image moderation runs before background removal.
- Only then does the cutout pipeline execute.
Failure is intentionally closed for safety-critical steps:
- no authenticated session
- blocked or review-required account
- stale or missing policy acceptance
- failed Turnstile challenge when enabled
- moderation provider failure when
MODERATION_FAIL_CLOSED=1 - moderation decisions that are blocked or uncertain
The default privacy posture is no image retention:
- raw uploads are processed in memory only
- output PNGs are returned directly and not persisted
- audit logs store request identifiers, digests, status codes, and moderation decisions only
/termspresents the user-facing Terms of Use, including permitted use, prohibited use, safety review, account enforcement, no-retention posture, and beta availability./api/sessionexposes whether the user is signed in, whether the current policy is accepted, the user status, whether the session is admin-capable, and whether moderation is active./api/remove-backgroundenforces auth, CSRF verification, account state, policy acceptance, Turnstile, moderation, payload validation, and rate limiting./api/report-abuselets signed-in users submit abuse reports tied to a request ID./api/admin/review,/api/admin/users/:userId/status, and/api/admin/reports/:reportId/reviewprovide a minimal review surface for admins listed inADMIN_EMAILS./api/healthreports process liveness./api/readinessreports dependency readiness for Postgres and moderation.- Node and Sites responses include baseline browser hardening headers: CSP, no-sniff, no-referrer, opener isolation, permissions policy, and HSTS where HTTPS is expected.
Copy .env.example to .env and set the values required for your environment.
Core variables:
SITE_URL: canonical public base URL used for auth callbacks and production linksDATABASE_URL: managed Postgres connection string used for users, sessions, policy acceptance, audit events, abuse reports, and moderation decisionsDATABASE_SSL: set to1when your Postgres host requires SSLSESSION_SECRET: cookie signing secretADMIN_EMAILS: comma-separated admin allowlistACCEPTABLE_USE_VERSION: policy version that must be accepted before processingSEGMENTATION_MODEL: local segmentation model size; this beta defaults tosmallto keep deployment payloads practical
GitHub auth:
GITHUB_CLIENT_IDGITHUB_CLIENT_SECRETGITHUB_CALLBACK_URL
Human verification:
TURNSTILE_SITE_KEYTURNSTILE_SECRET_KEY
Moderation:
MODERATION_PROVIDERMODERATION_MODELMODERATION_FAIL_CLOSEDOPENAI_API_KEY
Current implementation notes:
- the moderation abstraction is provider-driven, but this repo currently implements
openaianddisabled - the session store falls back to in-memory mode only when
DATABASE_URLis absent; production beta deployment should always provide Postgres - only the small local segmentation model is vendored; larger model variants should be added through a dedicated artifact path before enabling them
Install dependencies:
npm installRun the API and frontend together:
npm run devBuild the product:
npm run buildVerify the generated Sites runtime:
npm run verify:sitesRun a launch preflight against the current environment:
npm run deploy:preflightPrepare or verify the managed Postgres schema:
npm run db:prepareServe the built client through the API:
npm run startRun the test suite:
npm testSecurity audit:
npm auditGitHub Actions runs npm ci, npm test, npm run build, npm run verify:sites, and
npm audit --audit-level=moderate on pushes to main and pull requests.
Single image:
node ./src/cli.js image --input ./photos/person.jpgBatch a directory:
node ./src/cli.js batch --input ./photos --output ./exports --recursiveNotes:
- output is always PNG because transparency is required
- the segmentation backend is tuned for person photos and may underperform on non-person images
- batch mode continues through failures so one bad file does not abort the whole directory run
The production data store is keyed by DATABASE_URL and includes:
userspolicy_acceptancesaudit_eventsabuse_reportsmoderation_decisions- Postgres-backed session rows via
connect-pg-simple
This repo is wired for Sites with .openai/hosting.json.
Public deployment:
- Title:
Cutout Studio - URL:
https://cutout-studio.tim-o-finch.chatgpt.site - Slug:
cutout-studio
Before a real public beta launch, set production environment variables for:
- GitHub OAuth
- managed Postgres
- moderation provider credentials
- Turnstile
SITE_URLset to the final deployed URL
Without those values, the site can render but it will not satisfy the strict verified beta flow described above.
The Sites artifact is intentionally packaged with a dependency-free runtime shim. Until production secrets are configured, it serves the app shell and fail-closed API responses rather than running background removal without GitHub login, Postgres, moderation, and verification.
Recommended production launch sequence:
- Set the required runtime variables in Sites.
- Run
npm run deploy:preflightlocally against the same values. - Run
npm run db:prepareagainst the managed Postgres database. - Verify
npm test,npm run build, andnpm audit. - Save and deploy the matching Sites version.
- Confirm
/api/healthand/api/readinessare green on the live URL. - Update the portfolio launch post and project page with the public beta link.
- config validation for durable auth requirements
- CSRF token checks for signed-in write requests
- anonymous, blocked, and stale-policy processing rejections
- moderation fail-closed behavior
- moderation block logging
- successful processing audit logging
- abuse report creation
- readiness degradation reporting
- database readiness without
DATABASE_URL - admin account review actions

