* v0.6.29: login improvements, posthog telemetry (#4026) * feat(posthog): Add tracking on mothership abort (#4023) Co-authored-by: Theodore Li <theo@sim.ai> * fix(login): fix captcha headers for manual login (#4025) * fix(signup): fix turnstile key loading * fix(login): fix captcha header passing * Catch user already exists, remove login form captcha * feat(credentials): add Atlassian service account credentials * improvement(credentials): tighten Atlassian service account plumbing - Collapse fetchOAuthTokenBundle into fetchOAuthToken (returns the bundle) - Reuse serviceAccountJsonSchema in the JSON form instead of hand-rolled checks - Use parseAtlassianErrorMessage for log details; drop one-line bearer helper - Extract ATLASSIAN_SERVICE_ACCOUNT_PROVIDER_ID/_SECRET_TYPE constants - Use Drizzle .returning() instead of post-insert SELECT - Helper for the duplicated 401/403 + non-OK pattern in the validator * docs(credentials): add Atlassian service account setup guide - New /integrations/atlassian-service-account doc covers token creation, scope selection, and adding the credential to Sim - Form's "View setup guide" link now points at the doc - Fix the existing Google form link that pointed to the wrong path Screenshot TODOs left inline as MDX comments for the docs team. * docs(credentials): add Atlassian service account screenshots - Auth type picker, Sim add-credential modal, Jira block credential dropdown - Scope-picker screenshot still TODO * docs(credentials): add Atlassian scope picker screenshot * fix(credentials): address greptile feedback on Atlassian SA - Drop stale 'email and API token' copy from the service description (we only collect a token + domain, no email field) - Move duplicate display-name check inside the create transaction so concurrent POSTs can't both pass the check and insert duplicates * fix(docs): move Atlassian screenshots to docs/public Docs site serves /static/* from apps/docs/public, not apps/sim/public — matches the existing google-service-account screenshot convention. * fix(credentials): address review feedback on Atlassian SA - SSRF: only accept *.atlassian.net / *.jira-dev.com hosts before fetching tenant_info, blocking probes against localhost/internal IPs - Confluence spaces selector: pull cloudId from the SA secret instead of calling accessible-resources, which 401s for scoped service-account tokens - Case-insensitive https?:// strip so HTTPS://team.atlassian.net normalizes correctly * chore: merge staging and bump API validation route baseline to 727 * perf(credentials): single-resolve in confluence spaces selector Atlassian SAs were hitting resolveOAuthAccountId twice (once via refreshAccessTokenIfNeeded, once directly to read cloudId) and decrypting the secret twice (via getAtlassianServiceAccountToken inside refresh, then again via getAtlassianServiceAccountSecret). Resolve once up front and branch the whole flow on the result — SA path skips refresh entirely and pulls token+cloudId from a single secret read. * refactor(credentials): consolidate Atlassian SA creation into /api/credentials Atlassian service-account creation lived in its own route, contract, and mutation hook, copy-pasting ~140 lines of insert/membership/audit/posthog boilerplate from /api/credentials. Two endpoints means two authz paths, two audit shapes, two TOCTOU stories — they will drift. Fold Atlassian into the existing service_account branch of /api/credentials, dispatching by providerId. The Atlassian validator (tenant_info + Bearer /myself, SSRF host allowlist, typed error codes) lives in lib/credentials/atlassian-service-account.ts and is the only Atlassian- specific piece left. AtlassianValidationError maps to a {code, error} 400 in the existing catch block; the rest of the flow (transaction, members, audit, posthog, dup-check) is now shared with Google SA + env credentials. Delete: - /api/auth/atlassian-service-account route - contracts/atlassian-service-account.ts + barrel export - useCreateAtlassianServiceAccount hook - API audit baseline 727 → 726 Both forms (Google JSON-key, Atlassian token+domain) now call useCreateWorkspaceCredential with the appropriate body shape. * fix(credentials): close TOCTOU and restore typed errors after consolidation - Add inner duplicate-guard inside the create transaction (DuplicateCredentialError) to close the race that the outer findExistingCredentialBySource leaves open. service_account rows have no DB-level unique index on (workspaceId, providerId, displayName), so this is the actual safety net. Tx-internal check applies to Google + env_workspace too — race-safety win for all credential types. - Re-emit {code: 'duplicate_display_name', error: ...} on conflict so the form's ERROR_MESSAGES.duplicate_display_name mapping is reachable again. - Thread Atlassian-specific audit metadata (atlassianDomain, atlassianCloudId) back into recordAudit; consolidation had dropped them. - Use ATLASSIAN_SERVICE_ACCOUNT_PROVIDER_ID constant in contract superRefine. - Drop `error: any` in catch in favor of `error: unknown` + getPostgresErrorCode. * chore(credentials): drop dead createWorkspaceCredentialBodySchema + updateWorkspaceCredentialBodySchema Both shadowed the actually-used schemas (createCredentialBodySchema / updateCredentialByIdBodySchema) and were missing the apiToken/domain Atlassian fields. A future change could pick the wrong one and silently drop those fields. Confirmed zero non-definition references in the repo (grep across apps/, packages/, scripts/ minus build artifacts). * fix(credentials): scope inner duplicate re-check to service_account OAuth dedupes by accountId, env_* by envKey — both have DB-level partial unique indexes that surface as 23505. The previous inner re-check fired for all types and always threw DuplicateCredentialError, which mapped to 'duplicate_display_name' in the UI even when the real conflict was a duplicate OAuth account or env key. Restrict the in-tx re-check to service_account (the only type without a DB-level index) and let the 23505 handler emit a generic message for everything else. --------- Co-authored-by: Waleed <walif6@gmail.com> Co-authored-by: Siddharth Ganesan <33737564+Sg312@users.noreply.github.com> Co-authored-by: Vikhyath Mondreti <vikhyathvikku@gmail.com>
The open-source platform to build AI agents and run your agentic workforce. Connect 1,000+ integrations and LLMs to orchestrate agentic workflows.
Build Workflows with Ease
Design agent workflows visually on a canvas—connect agents, tools, and blocks, then run them instantly.
Supercharge with Copilot
Leverage Copilot to generate nodes, fix errors, and iterate on flows directly from natural language.
Integrate Vector Databases
Upload documents to a vector store and let agents answer questions grounded in your specific content.
Quickstart
Cloud-hosted: sim.ai
Self-hosted: NPM Package
npx simstudio
Note
Docker must be installed and running on your machine.
Options
| Flag | Description |
|---|---|
-p, --port <port> |
Port to run Sim on (default 3000) |
--no-pull |
Skip pulling latest Docker images |
Self-hosted: Docker Compose
git clone https://github.com/simstudioai/sim.git && cd sim
docker compose -f docker-compose.prod.yml up -d
Sim also supports local models via Ollama and vLLM — see the Docker self-hosting docs for setup details.
Self-hosted: Manual Setup
Requirements: Bun, Node.js v20+, PostgreSQL 12+ with pgvector
- Clone and install:
git clone https://github.com/simstudioai/sim.git
cd sim
bun install
bun run prepare # Set up pre-commit hooks
- Set up PostgreSQL with pgvector:
docker run --name simstudio-db -e POSTGRES_PASSWORD=your_password -e POSTGRES_DB=simstudio -p 5432:5432 -d pgvector/pgvector:pg17
Or install manually via the pgvector guide.
- Configure environment:
cp apps/sim/.env.example apps/sim/.env
# Create your secrets
perl -i -pe "s/your_encryption_key/$(openssl rand -hex 32)/" apps/sim/.env
perl -i -pe "s/your_internal_api_secret/$(openssl rand -hex 32)/" apps/sim/.env
perl -i -pe "s/your_api_encryption_key/$(openssl rand -hex 32)/" apps/sim/.env
# DB configs for migration
cp packages/db/.env.example packages/db/.env
# Edit both .env files to set DATABASE_URL="postgresql://postgres:your_password@localhost:5432/simstudio"
- Run migrations:
cd packages/db && bun run db:migrate
- Start development servers:
bun run dev:full # Starts Next.js app and realtime socket server
Or run separately: bun run dev (Next.js) and cd apps/sim && bun run dev:sockets (realtime).
Copilot API Keys
Copilot is a Sim-managed service. To use Copilot on a self-hosted instance:
- Go to https://sim.ai → Settings → Copilot and generate a Copilot API key
- Set
COPILOT_API_KEYenvironment variable in your self-hosted apps/sim/.env file to that value
Environment Variables
See the environment variables reference for the full list, or apps/sim/.env.example for defaults.
Tech Stack
- Framework: Next.js (App Router)
- Runtime: Bun
- Database: PostgreSQL with Drizzle ORM
- Authentication: Better Auth
- Schema Validation: Zod
- UI: Shadcn, Tailwind CSS
- Streaming Markdown: Streamdown
- State Management: Zustand, TanStack Query
- Flow Editor: ReactFlow
- Docs: Fumadocs
- Monorepo: Turborepo
- Realtime: Socket.io
- Background Jobs: Trigger.dev
- Remote Code Execution: E2B
- Isolated Code Execution: isolated-vm
Contributing
We welcome contributions! Please see our Contributing Guide for details.
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Made with ❤️ by the Sim Team


