Protecting the private key in a compiled application

Hi there,

We’ve built a prototype of Riff.CC using Ceramic and ComposeDB, which uses it to store IPFS pin data. We’re doing so via a private key which is associated with a DID which is added as an admin on the Ceramic node. Then access controls are implemented using Ethereum accounts.

We’re hoping to avoid exposing the private key to the user, so that they cannot get around the Ethereum access controls. Right now that looks like deploying on Vercel with encrypted environment vars, but that feels a bit like an ugly hack.

Instructions are here for the Ceramic node we’re running - GitHub - riffcc/ceramic-node
and here for the web application we’re running - GitHub - riffcc/ceramic-riff-web: Riff.CC, implemented using ComposeDB and Ceramic.

Are we using ComposeDB wrong? :sweat_smile:

1 Like

I’m commenting here to follow the thread, to make sure we do it correctly as well :slight_smile:

Without knowing how your app works, will the client UI load code that uses these environment variables? If so I don’t believe the encryption helps you out, the encryption only protect them from being plain-text in server build logs (I think). The client user could set breakpoints in the browser and view environment variables which are part of any code that is served up to the client/browser.

At least for WalletChat, whenever we run into this we use our own API to act as middleware between the client and servers, to protect any private keys such as this, or paid API tokens we know a client could steal/re-use if they inspected our client code.

In Ceramic (and therefore ComposeDB) DIDs control streams so there’s no built-in way to do access control with Ethereum.

If you want create specific control mechanisms, you can do so by having your service control streams and allow your users to interact with them based on your access control logic, but that means your users can’t “own” the streams, at least when it comes to Ceramic’s logic.
Fundamentally you can’t at the same time have your users control their streams and restrict them with your own logic, it has to be one or the other.

Regarding your private keys in particular, it’s something only your server should have access to, not your client and end-users in any case.

1 Like

Hi Paul, thanks for the reply!

We’re building a platform where users can submit uploads (an ipfs hash and some metadata), and then moderators can approve or reject those uploads to allow or prevent them from appearing on the front page. We’d also like for moderators to be able to make minor edits to descriptions and the like.

Would an alternate approach be to allow the users to control their own streams, then have the website control its own stream?

In this hypothetical, the website could maintain a list of what’s approved and not approved, and only allow Eth admins access to change that stream. It could also maintain a list of edits to the content.

Is there some way to “partially override” the contents of a stream by taking changes from a different stream, and render it?

Regarding your private keys in particular, it’s something only your server should have access to, not your client and end-users in any case.

Agreed. As implemented I haven’t been able to confirm for sure that the keys are exposed to the user, but I’m fairly certain they are.

1 Like

Yes from what you describe it seems like there isn’t a high need for your users to control their submissions, mainly there doesn’t seem to be a need to update them after they are created, is there?

Considering you also want moderators to possibly change the contents, these streams will have to be controlled by your app anyways, so the simplest solution is probably to create them directly in your app’s backend.

It may seem silly, but we really want to do it as described - particularly because we want users to be able to submit their uploads to sites running the same software that aren’t our own.

Our hope is we could just track the difference between a users submission and our view of it somehow. Particularly because we want to run a service that scales effortlessly, and if we control all the streams that seems a lot harder to do past a certain point.

1 Like

For sure you can implement different solutions based on your needs, for example you can use relations to point to “curated” streams that are not controlled by your app.

1 Like

hey wings, welcome to the forum - looks like this one is resolved but let me know if you have unanswered questions!

also, excited to see what you build - we have a channel for sharing your project Ceramic and also a grants program