The Environment Sharing Platform is a secure web application that enables development teams to safely manage, store, and share environment variables without exposing sensitive credentials through insecure channels like Slack or email. Built with Next.js and MongoDB, it provides an encrypted, centralized vault for all your environment variables.
Organization owners, admins and members
└ Team each member is an Editor or a Viewer
└ Project one app or service
└ Environment development, staging, production, … (each with its own variables)
| Role | Can do |
|---|---|
| Org owner | Everything, plus delete the org, transfer ownership, require two-factor, reset a member's 2FA |
| Org admin | Create teams, invite people, change roles, edit every project, view the audit log |
| Org member | See only the teams they're on |
| Team editor | Read and change variables, create projects and environments in that team |
| Team viewer | Read variables only |
- Organizations, teams and projects - Org owners and admins create teams and decide who can edit and who can only read
- Multiple environments per project - development, staging and production out of the box; add your own
- Sign in with Google - Accounts are created with Google; people can add a password in Account settings for email sign-in
- Passkeys and authenticator apps - Optional second step at sign-in (Touch ID, Face ID, Windows Hello, a password manager, or 6-digit codes), with one-time backup codes. Owners can require it for their organization
- Values stay hidden until you confirm - People with two-factor confirm with a passkey or code before secret values are sent to the browser; the unlock lasts 10 minutes and lives on the server
- Restricted projects - Limit a project to selected team members; move projects between teams
- Invitations - 10-character invite codes (also shareable as a link) that expire and can be limited to a number of uses. Envoy doesn't send email.
- Audit log - Owners and admins see every change to members, teams, projects and variables (key names only, never values)
- Personal API tokens - Fetch variables from the CLI or CI; tokens follow the user's current access
- Encrypted at rest - AES-256-GCM, decrypted only for people with access
- Safe concurrent editing - Saves are versioned, so two editors can't silently overwrite each other
- Temporary links - Share a .env once without an account; links expire within 24 hours and are deleted. Environments are never public.
- Monochrome UI - shadcn/ui, dark and light themes, ⌘K command menu, keyboard shortcuts, responsive down to mobile
- Rate Limiting - Built-in rate limiting to prevent abuse and ensure system stability
- NodeJS and Python SDK - Fetch environment variables directly from the terminal
- Next.js 15 (App Router) and TypeScript 5
- shadcn/ui (Radix primitives) with Tailwind CSS 4, monochrome theme tokens in
src/app/globals.css - Geist Sans / Geist Mono fonts, Lucide icons, cmdk command menu, sonner toasts
- SWR for client data fetching, next-themes for dark/light
- Next.js route handlers under
src/app/api - MongoDB with Mongoose
- NextAuth.js (Google + email/password) with an optional passkey or TOTP second factor
- SimpleWebAuthn for passkeys (only public keys stored, single-use challenges)
- otpauth + qrcode for TOTP enrollment and verification (replay-protected, rate-limited)
- bcryptjs for password hashing; backup codes and API tokens are stored as SHA-256 hashes
- Node
cryptoAES-256-GCM for values at rest (crypto-jsonly to read legacy values) - zod request validation, rate-limiter-flexible rate limiting
- Node.js 20.12 or newer
- MongoDB database
- npm or yarn package manager
- Clone the repository:
git clone https://github.com/GDGVIT/envoy.git
cd envoy/web-app- Install dependencies:
npm install- Set up environment variables:
Create a
.env.localfile in theweb-appdirectory with the following variables:
# Database
NEXT_MONGO_URI=your_mongodb_connection_string
# NextAuth Configuration
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your_nextauth_secret
#Google oAuth Credentials
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
# Encryption (server only; use a long random value and keep it backed up)
ENCRYPTION_SECRET=your_long_random_encryption_key
#Others
NEXT_PUBLIC_APP_NAME=your_app_nameENCRYPTION_SECRET is used only by server-side code and must stay the same for as long as encrypted data needs to be read: it encrypts variable values, temporary links and authenticator-app secrets. Changing it makes that data unreadable (nothing is deleted; restoring the old value fixes it), so keep it backed up.
Optional: WEBAUTHN_RP_ID and WEBAUTHN_ORIGIN pin passkeys to one domain (e.g. envoy.example.com and https://envoy.example.com). Without them, passkeys belong to whichever domain they were created on.
Start the development server:
npm run devThe application will be available at http://localhost:3000
Build and start the production server:
npm run build
npm startnpm run lint
npm run typecheck- In the app, open Account → API tokens and create a token.
- Fetch an environment (every project page has a Use from CLI button with the exact URL):
export ENVOY_TOKEN=envoy_pat_…
# write a .env file
curl -fsS -H "Authorization: Bearer $ENVOY_TOKEN" \
"https://your-envoy-host/api/v1/<org>/<team>/<project>/<environment>?format=dotenv" > .env
# or get JSON: { "vars": { "KEY": "value" }, "version": 3, … }
curl -fsS -H "Authorization: Bearer $ENVOY_TOKEN" \
"https://your-envoy-host/api/v1/<org>/<team>/<project>/<environment>"Tokens act with the owner's current access: removing someone from a team (or the org) immediately cuts off their tokens too. Revoke a token from the same page.
List endpoints (organizations, members, team projects and members, invite links, API tokens, audit log) return one page at a time:
?limit=sets the page size: default 50, at most 100.- Each response includes
nextCursor. Pass it back as?cursor=to get the next page; it isnullon the last page. - Cursors are opaque and stay stable when items are added or removed between requests.
- Some lists also return
total. Org members accept?q=to search by name or email.
Envoy used to organize variables as Workspaces → Groups. Existing data has been moved to Organizations → Teams → Projects → Environments.
- Group tokens no longer work.
GET /api/env/getreturns410 Gone; use personal API tokens and/api/v1/…. - Nothing can be made public. Use invite links, or temporary links (at most 24 hours) for one-off sharing.
- Invitations are 10-character codes (
XXXXX-XXXXX), also usable as an/invite/<code>link. Envoy doesn't send email invites.
web-app/
├── src/
│ ├── app/
│ │ ├── (auth)/ # login, signup, 2FA setup/verify, onboarding, invite links
│ │ ├── (app)/ # signed-in app: /o/[org]/…, /account
│ │ ├── share/ # temporary links (expire within 24h)
│ │ └── api/ # route handlers (orgs, teams, projects, envs, invites, tokens, 2fa, v1)
│ ├── components/
│ │ ├── ui/ # shadcn/ui components
│ │ ├── app/ # app shell, env editor, command menu
│ │ └── landing/ # marketing page
│ ├── lib/ # auth, authorization, audit, totp, validation, dotenv
│ ├── models/ # Mongoose schemas
│ └── utils/ # encryption, rate limiting, db connection
└── public/
|
Chirayu Sahu
Frontend / Backend |
Humaidh
Security |
Made with ❤ by GDG VIT