Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Secrets support #1492

Open
nicholaschiang opened this issue Jun 2, 2021 · 15 comments
Open

Secrets support #1492

nicholaschiang opened this issue Jun 2, 2021 · 15 comments

Comments

@nicholaschiang
Copy link

Is your feature request related to a problem? Please describe.

I'd like to be able to specify API secrets in a StackBlitz project without sharing them publicly. I'm fine with the code being shared publicly (because the repository itself is open-source), but I don't want to have certain environment variables (e.g. API keys, secret tokens) shared publicly.

Describe the solution you'd like

I'd like to be able to specify secrets in a project's settings (that are only accessible via process.env when I'm logged in). Essentially, I just want StackBlitz to have CodeSandbox's existing secrets feature.

Describe alternatives you've considered

I could (if it's possible) create a private StackBlitz project and then just add the environment variables in a .env.local file.

Additional context

I'm trying to get Tutorbook working as a StackBlitz project so that I can edit on the go (via any web browser) wherever I am.

@mwisnicki
Copy link

There's an ugly workaround for frontend code - put them into localstorage of preview frame.

@mwisnicki
Copy link

And you can copy them into cookie to access them from node :)

@FossPrime
Copy link

FossPrime commented Apr 4, 2022

And you can copy them into cookie to access them from node :)

@mwisnicki Do you have some sample node code for this? What you're proposing is extremely unusual... accessing browser LocalStorage from node.js

I'm unable to access LocalStorage from node as expected.

@FossPrime
Copy link

FossPrime commented Jun 16, 2022

Has anyone made a secrets example in SB? Like a way to have a public sandbox that uses database passwords safely? I know this is not supported, @d3lm should we expect this in 2022, or should we workaround it now? Has anyone made an example of a Cookie based approach to storing secrets locally in a not to inconvenient way, one that shares the secret with the WC Node.js?

Also happy one year anniversary for this issue.

Codesandbox knocked this one off the park IMO, that was one of the few things I didn't complain about when I was using them: https://codesandbox.io/docs/secrets (They didn't even support Vite in sandboxes until I bugged them about it a few months ago)

@mwisnicki
Copy link

mwisnicki commented Jun 17, 2022

Unfortunately cookies seem to not work in StackBlitz so as an alternative I'm passing secrets explicitly to an api endpoint and then reload the page:

https://stackblitz.com/edit/node-secrets-example-localstorage?file=index.js

@FossPrime
Copy link

Unfortunately cookies seem to not work in StackBlitz so as an alternative I'm passing secrets explicitly to an api endpoint and then reload the page:

https://stackblitz.com/edit/node-secrets-example-localstorage?file=index.js

Wow, that is not what I would have done. My idea was to store the secrets in local storage and then pass them to the server with websockets or in url parameters in a fetch request.

Your idea is better, somehow... I have a strong feeling it can work... We just need to whitelist what cookies we allow and specify where to expect them from... Standby, Sandbox incoming

@mwisnicki
Copy link

mwisnicki commented Jun 17, 2022

You can also override fetch to always pass secrets in headers. Might be easier that way.

@mwisnicki
Copy link

mwisnicki commented Jun 17, 2022

Actually I think the cleanest solution would be something that works similar to login pages:

  • setup express middleware that checks if secrets are present and if not redirects to init page
  • single init page that copies secrets from localstorage to backend and does redirect back to referrer (you could pass secrets as headers of this redirect)

@mwisnicki
Copy link

Example code: https://stackblitz.com/edit/node-secrets-example-localstorage-v2?file=localStorageSecrets.js

@FossPrime
Copy link

FossPrime commented Jun 17, 2022

https://stackblitz.com/edit/secrets-demo

I had a million ideas, only three work well enough right now.

  • Transmit cookies via Query params
  • Transmit via WebSockets
  • Transmit via a multi-part form payload

These do not work:

  • Cookies sent via HTTP requests (I tried CORS a million times to no avail)
  • Custom header params (these stall the connection, even when they are whitelisted by CORS)

For my uses, an ESM module that handles this would work fine. I always use Vite, so a vite plugin that stalls bootup until it receives secrets would be fine for me. Deleting secrets may need a cache clear. I'd also like the solution to work on incognito mode... which restricts cookies and serviceWorkers... but sessionstorage and localstorage seem to work fine. localstorage is sometimes unavailable for dumb reasons, like if safari is running in instagram.

Port based ideas or ones that run on a detached spawn have an issue of, how do we communicate the secret while maintaining Vavite/Vite HMR, when we don't have IPC. We could save them to a file like /tmp/secrets.json. That approach is obviously not very portable to baremetal. We could save them to a Vite loaded module like /tmp/secrets/CAT_API.ts, that would be ideal for HMR.

The best solution would be

  • Easy to integrate
  • Portable to bare-metal, glitch, Cloudflare Workers, CodeSandbox, WebContainers API powered Vercel apps.
  • Low weight
  • Low maintenance
  • Fast to update, ie Easy to delete and manage entries while not requiring a full SB reload (a UI would be ideal)
    • This could be done on another reserved port or as a web component like SB, SlideEv and Svelte do embeds
  • Easy to export or sync to the cloud, somehow
    • Perhaps by being compatible with password managers?
  • Compatible with HMR, If I use a secret in one deep module, it should not require a full server or client reload.
    • Vite has really good support for JSON module loading as if they were ESM...

Update from Discord's sylwiavargas

So .jshrc is the only file that is synced to localstorage (besides .jsh_history for the terminal history, but it should not be changed manually so let's ignore this one). But, it's across every single project. This means that if I add my secrets to .jshrc with export MY_SUPER_SECRET_GITHUB_TOKEN=1234, then my project can use process.env.MY_SUPER_SECRET_GITHUB_TOKEN . And it will still work after a refresh. This also means, that if you sent me a StackBlitz link you created, which reads the .jshrc from MY account, you can send it to your own server. So using secrets in .jshrc can be done, but you should be very careful. I always give them very limited access so if they leak, it doesn't really matter too much. And then you can remove them after you ran the project.

You can argue that using secrets in .jshrc is somewhat the same risk as doing that on local because you don't know what an npm install from a random github repo does on your machine but at the same time, it's easier to send a StackBlitz link to someone.

(this explanation came from the wonderful https://twitter.com/SamVerschueren who's generally great at explaining things if you're looking to follow some StackBlitz folks on

Twitter)

  1. This opens two other ideas... We can store base64 enoded secrets keyed by their project slug there
  2. We can hijack node and launch our own secrets server for every sandbox.

Not sure if this provides cross device sync... Developing

@richpowell
Copy link

richpowell commented Jul 5, 2022

Could an integration with doppler work for secrets management across sb? https://www.doppler.com/integrations

@FossPrime
Copy link

Could an integration with doppler work for secrets management across sb? https://www.doppler.com/integrations

StackBlitz has no such thing as a secure side and a public side. This makes Runkit, Code spaces, codesandbox or Kubernetes style secrets mathematically impossible.

There are two workarounds:

  1. Have secrets that are only seen and used by a handful of authorized users.
  2. Change what StackBlitz is fundamentally, and deploy sandboxes to something like Runkit with secrets in tow.

@FossPrime
Copy link

https://vitejs.dev/guide/api-plugin.html#client-server-communication

This is a new solution that could be really neat for projects that run vite.

The idea is to fetch localStorage keys beginning with secret-. If none are found and you have the plugin installed, overlay a form on screen to enter secrets. Once the secrets are loaded, they are passed as environment variables to import.meta.env.SECRETS

@FossPrime
Copy link

https://stackblitz.com/edit/vitejs-vite-itctul?file=package.json&terminal=m,y,%20,s,e,c,r,e,t,%20,m,e,s,s,a,g,e,dev

If you set your browser to forget site history... this might work. It's probably better than storing secrets in your sandbox. For secrets longer than 16 characters... it will take a while.

@retrohacker
Copy link

retrohacker commented Feb 2, 2023

Popping on in to say I'm building a demo for a conference that uses the OpenAI API. I'd like for conference attendees to be able to use the project, but it currently requires setting env vars.

Having a way to configure and inject env vars into a StackBlitz project without sharing them would be a big win for this use case.

The feature would be a secret store that StackBlitz manages for a project per account instead of per project. When starting the project for the first time you'd be prompted to hydrate the secrets with your own values.

For some inspiration, Autocode has a decent approach to this: https://autocode.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants