This might be a stupid question, but — I’m using Observable for code examples for a company with a private API, to show customers how to use our API data to do various things. Since you can’t use Secrets in a shared notebook, and since hardcoding credentials is obviously a bad idea, I settled on using Inputs to ask for API credentials, since those don’t appear to be saved with the notebook, only run on the client side.
That allows a customer to change some inputs to our API and provide their own credentials, and then run our code examples with live feedback.
Is that a good idea? My gut tells me it isn’t, but I can’t think of a better way to do it at the moment. Especially not one that easily allows customers to provide their own API credentials in a secure(ish) way.
It should be ok: afaik, the values of specific HTML inputs aren’t captured/logged by Observable. So if you have something like
viewof token = html`<input type=password>`
And every reader to that notebook pastes in their own secret, then that secret shouldn’t be stored in Observable database (as far as I know), and it will only be kept in the reader’s page session.
But if this is actually 100% secure™, I’d love to hear other people’s thoughts on this. Because if you’re going to be given the secrets to every reader in plaintext via some other method, that might be introduce more complexity/more room to make a mistake. It’s also possible that you are using a malicious 3rd party JS library that query for input[type=password] elements and sends those values to some shady remote server, but if you’re using well-used libraries like d3 and all I seriously doubt that would be an issue.
See also Encrypted Message for a potentially more secure/easier to distribute option…
Another option: Create a team, add yourself as an editor, make a private team notebook with a Secret. Then, add other people as “readers” (should be free), who can access the private team notebook and view the contents of the notebook/secret securely. It would be $7 a month for you, but much easier than juggling around secrets off-platform imo.
Alexander and Tom have already given great answers, but I want to confirm from the Observable side that we do not log or save anything you put into Inputs.
“What gets sent to Observable and what doesn’t” comes up a lot, and we’d love to figure out how to make it clearer within the product. The big distinction is that the contents of the gray-background code editor are saved to Observable servers, and the white-background page (the output of that code) runs entirely on the user’s computer. Here’s my rough attempt at a diagram:
As for your specific use case, Tom has been doing a ton of interesting work in that area, so there may be no better answer than his!
Here’s an example where our coworker Visnu includes a utility (to convert a username/password to a database connection URL) that only runs locally in the user’s browser, with the explicit caveat: “You should be wary of any form on the internet prompting you for a password! Feel free to inspect this code to ensure nothing nefarious is happening.”
I’m no security expert, so here I have to balance my excitement about the possibilities of the notebook medium against the generally prudential advice not to ask users to enter credentials anywhere other than a single clear secure sanctioned login page.
Is it a read-only API? Are all the calls idempotent? Could fiddling with a cell (in the playful mindset of someone exploring docs and examples) potentially do something destructive? Would the user understand that if they loaded more code on the page (e.g. adding a cell requiring a library), it could potentially access their credentials? Would they be able to distinguish a safe notebook from a malicious one?
Without knowing your API, I guess my advice is probably to include mock responses (e.g. from a file attachment or loaded from a static JSON somewhere) so that readers can explore the real syntax and schemas in a safe, harmless, playful sandbox.