Is it possible to create Streams controlled by multiple DID?

For example, we are building a counter app where everyone could visit a page and clicked a button so that the counter will be incremented to record globally the clicks count.

  1. One way to do it would be created a stream using admin key in the backend, and every time people click, we trigger the backend logic to update the counter. (This is likely trivial? But admin has centralized power to change the counter)

  2. Whenever user click, they create a new counter stream, and the backend simply render how many such “Count” stream exist. (This is likely to work but now every application state is easily modelled this way)

3. Is there any other ways to update the counter directly on by the users? (One single Stream controlled by multiple DIDs, is this possible? or could admin delegate control of the Stream to each user using CACAO?)

1 Like

Having multiple DID controllers for a single stream isn’t supported.

You could technically use CACAO to delegate access to user DIDs but that inverts the normal flow of control using CACAO - user’s delegate permissions to apps and not the other way round.

Plus, your stream will still be owned by the app/admin DID, not by the users. The app can choose not to allow users access to that stream at any time.

Along the same lines as your 2nd suggestion, you could possibly use ComposeDB to allow users to create/update streams in a CounterModel or something, and the app could rollup the number of +1 updates across all user streams in that model.

This is likely to work but now every application state is easily modelled this way

I’m not sure I understand what you mean by this ^?

@spencer, am I on the right track?

1 Like

Yes this is right. Current recommendation would probably be to do the counter approach where each user creates a new document in the counter Model. Long term, we hope to eventually support more collaborative multi-writer documents, but there are no concrete plans in the near term to build such a thing. For now, Ceramic and ComposeDB are optimized for data with a single owner.


Good question!!!!!!!!!!!


I see, so in the short term futures, the main programming model will be “event sourcing”-like and who ever trigger the actions will likely be the owner of the streams.

In other words, any state that can be modified by multiple parties should be decomposed into multiple pieces each owned by one user or the project admin key.


Yes, that’s correct.

But the spec seems to indicate that in future multiple “controllers” might be supported? @spencer

type GenesisHeader struct {
  controllers [String]
  schema optional String
  family optional String
  tags optional [String]
  unique optional String

  • controllers - an array of DID strings that defines the controllers of the stream (i.e. who is allowed to make updates to it).
1 Like

Yeah, the controllers field is an array because at one point we thought we might want to support multiple controllers in the future. These days that is looking less likely to ever happen. More likely when we eventually support multi-writer streams they will still have a single DID controller, but with a more complex DID method based around something like a multisig so that multiple end users can write into the same stream even though it’s controlled by a single DID.

1 Like

more like meta-stream kinda construct? so again in short term the only way to “support” this is to emulate it in the application layer using CQRS/event sourcing

I love the idea of new did method!

So far ceramic is revolving around did of PEOPLE who holds a crypto keypair. But the D in DID is merely an identifier and could totally be referring to things or objects

@0xEE3CA4dd4CeB341691 have you had a look at the proposed new 3ID spec? It might do some of what you are interested in.

Never looked at it this way. I was assume 3id is more like an keychain where all keys in the 3id DID belongs to 1 single user. But if keys belong to different users, 3id does behave a lot like an multi-sig where the signing threshold is 1?