Only Admin Could create models/composites?

It seems that only admin did is authorized to create models. is this the case? Understanding that this is okay if every dev runs their own node. But in a world where public node operator run nodes on behalf of developers, this becomes tricky… Is it possible to show an “delegation” explicitly that admin is deploying on behalf of someone?

  private async _processAdminModelsMutationRequest(
    req: Request,
    res: Response,
    successCallback: AdminApiModelMutationMethod
  ): Promise<void> {
    // Parse request
    const jwsValidation = await this._validateAdminApiJWS(req.baseUrl, req.body.jws, true)
    if (jwsValidation.error) {
      res.status(StatusCodes.UNPROCESSABLE_ENTITY).json({ error: jwsValidation.error })

    // Authorize request
    try {
    } catch (e) {
      res.status(StatusCodes.UNAUTHORIZED).json({ error: e.message })

    // Process request
    await successCallback(jwsValidation.models)
    res.status(StatusCodes.OK).json({ result: 'success' })

Hey @0xEE3CA4dd4CeB341691. That’s true. You’ll need an admin DID configured for your node to be able to use specific models, create composites and perform data mutations.

Technically, this does not prevent other community members to become node operators and allow other devs to use those nodes. For example, we have a really cool ecosystem project One way how users can get access to a node is by a node provider sharing the Admin DID private key and a Ceramic URL to access the node.

1 Like

In theory a delegation from the Admin DID to another DID should be possible, but isn’t possible with the current implementation today. CC @msena @avi @jthor for the feature request


iirc model creation is limited to did:key accounts today, which is what the node “admin did” is. We have been tossing around the idea of allowing models to be created by a did:pkh to support creating models from e.g. a web app. @paul and @jthor have more info here.

1 Like

Interesting yes. Could be possible using an object-capability.

1 Like

Hi, there are different concepts mixed here so better look at them separately I think:

Multi-tenant nodes

Ceramic doesn’t have any multi-tenant logic. The only access control logic for the Ceramic node itself is whether API access is public or admin-only, with the API calls needing to be signed by a known admin DID set in configuration.
Admin DIDs have access to all the admin APIs, it is not possible for example to allow an admin DID to start indexing models but not stop indexing.
If you want to use Ceramic in a multi-tenant logic, you would need to implement the logic you need on top of the Ceramic node, maybe with a form of delegated access as you described.

Model creation

Models are Ceramic streams so they need an authenticated DID to create them. Currently, only the Key DID method is supported to create models to make them portable across networks, but it doesn’t need to be an admin DID, any Key DID can be used to create a model.

Model indexing

While a model can be created by an Key DID, indexing a model on a Ceramic node in order to keep track of the associated documents uses a restricted API that requires an admin DID.
By default the ComposeDB tools calls this API when creating and deploying composites, so an admin DID needs to be provided in these cases.

Development flow

For context, the expected development flow is as follows:

  1. Developers download the Ceramic and ComposeDB CLI and devtools, so they have a local Ceramic node with their own admin DID
  2. Developers deploy existing composites or create new ones on their local Ceramic node and develop their apps
  3. Once their apps are ready for deployment, developers deploy their composites to the target network (Clay testnet or mainnet for example) - this is where they might need to deploy to a Ceramic node with different admin DIDs

So it seems in your case it’s really about having a system to deploy composites to your multi-tenant deployment, maybe that could be done with a dedicated server that performs the necessary access control logic and performs the actual composite deployment using the admin DID?


Thanks for the comprehensive answer @paul Just want to make sure I understand here.

So it is possible for non-admin key did to create model? Which API should I use for that use case?

Is model creation and indexing two separate APIs or are they in general bundled in one call?

This is exactly what we are trying to achieve. We want to shorten the time & efforts before devs could deploy and interact with a model by removing the need of running their own node and using commandline workflow to create & deploy models. Currently we achieve this by deploying on behalf of users using our own admin key. But this is hard to associate who’s the model owner cuz all owned by our admin key. But I guess we could add that label in our centralized DB.

Yes, you can use the Composite.create() API, but you’ll need to make sure to set the index parameter to false as it is true by default, see here for more details about these parameters.

On the Ceramic node, these are 2 separate APIs:

  • A public API endpoint to create streams (models in this case)
  • A restricted (admin-only) API endpoint to specify what models to index

Now with the ComposeDB tools, these are abstracted as a composite that contains one or more models, that need to be stored and indexed on the Ceramic node in order to perform queries at runtime, so the models deployment and indexing concerns are usually bundled together.
Using the APIs you can opt-out from indexing when deploying a composite, but the CLI doesn’t expose this option.

I think simplifying the ability to deploy and index composites with multi-tenant nodes is very useful, but I’d advise against trying to replace the local development flows.
When working on their apps, I expect developers will need to be able to develop and test locally, having a local Ceramic and ComposeDB setup is going to be the easiest to create and evolve their data model, especially as they go through early iterations.

Another aspect to consider is that while there is currently no additional cost to deploying models to mainnet, once there are incentivizations in the network it’s likely the cost will be non-zero, so mainnet shouldn’t be the default network to use when iterating on data models development, it should be used for production only.

1 Like

So the more accurate way to put it would be:

  1. any key did could deploy new model
  2. only admin did could start index

I think this is how we got the impression that only admin could deploy model as last time we tried we got errors complaining about not using an admin did

any way to walk around the did:key requirement? with maybe cacao/did:pkh?

Using did-session to manage indexes / create composites - #4 by Joera a related thread.

At high level what need to be updated to support did:pkh?

  1. Remove the assertion that only did:key controllers are supported:
function assertSupportedModelController(model: Model): void {
  // if (!model.metadata.controller.startsWith('did:key:')) {
  //   throw new Error(
  //     `Unsupported model controller ${model.metadata.controller}, only did:key is supported`
  //   ) 
  // }
  1. Add logic to handle did:pkh controllers. This could look something like:
function assertSupportedModelController(model: Model): void {
  if (model.metadata.controller.startsWith('did:key:')) {
    // did:key logic
  } else if (model.metadata.controller.startsWith('did:pkh:')) {
    // did:pkh logic
  } else {
    throw new Error(
      `Unsupported model controller ${model.metadata.controller}, only did:key and did:pkh are supported`
  1. what else related to did:pkh methods and resolution do we need to update?

The problem of did:pkh is that sessions use CACAOs that need to be anchored, so a model created for one network wouldn’t be portable to another.
We have a project to support did:pkh eventually, but there’s more to it than simply adding a branch of logic in the model handler check.

1 Like

portable you mean reference models deployed in testnet from mainnet without redeploying?
Could you share a bit more on the did:pkh project? Would be happy to contribute if we could as it seems to be the roadblock stopping ppl from deploying using a shared/hosted node

Thanks for the insight! are you referring to this new CIP CIP: CapReg - object-capability registry by oed · Pull Request #127 · ceramicnetwork/CIPs · GitHub ?

@jthor @msena So is it intentional to only allow did:key to create model so that models are portable across mainnet and testnet?
However, this is not really the convention in Ethereum as you always need to redeploy contracts on mainnet

No, CapReg is something different.

What Paul was talking about is this project. Should be a fairly simple change to js-composedb:

So is it intentional to only allow did:key to create model so that models are portable across mainnet and testnet?

Yes exactly.

1 Like

will it always be the case? as we could adjust data model explorer according (eg. combining mainnet & testnet)

if we don’t rely on IPFS in future, it is not possible to have portable models from testnet to mainnet right?

Hm, well the nuance being that any Model instance documents for that model would only live on one of the networks. So I’m not sure what’s best from a product perspective.

So to add some nuance to the idea about “Not supporting IPFS”:

  1. We will keep supporting the IPLD data model that IPFS uses
  2. We will likely stop using bitswap for syncing data
  3. We will keep using libp2p

So in reality we are picking the pieces of IPFS that works for us and choosing not to use the other ones.