Only Admin Could create models/composites?

To support pkh, we need to check:

  1. must be cacao without expiry
  2. must has model stream as resource
function assertSupportedModelController(model: Model, ceramic: CeramicApi): void {
  const unsupported = `Unsupported model controller ${model.metadata.controller}`
  if (model.metadata.controller.startsWith('did:pkh:')){
    if (ceramic.context.did == null) {
      throw new Error(
        `${unsupported}, did missing from ceramic context`
      )
    }
    if (!ceramic.context.did.hasCapability()) {
      throw new Error(
        `${unsupported}, only did:pkh with CACAO is supported`
      )
    }
    const cacao: Cacao = ceramic.context.did.capability(); 
    if (cacao.p.exp == null) {
      throw new Error(
        `${unsupported}, only did:pkh CACAO without expiry is supported`
      )
    }
    const hasModelResource = cacao.p.resources?.includes(`ceramic://${MODEL_STREAM_ID}`)
    if (cacao.p.resources?.length != 1 || !hasModelResource) {
      throw new Error(
        `${unsupported}, only cacao with resource ${MODEL_STREAM_ID} is supported`
      )
    }
  } else if (!model.metadata.controller.startsWith('did:key:')) {
    throw new Error(
      `${unsupported}, only did:key is supported`
    )
  }
}

@jthor @paul something like this would do ?

Thatā€™s almost it! A few things to note:

  1. the resource needs to be ceramic://*?model=kh4q0ozorrgaq2mezktnrmdwleo1d, we sometimes refer to this as the ā€œmeta modelā€
  2. If we are about to create a new model, checking that the model is created ceramic.did with the correct CACAO is sufficient (e.g. here)
  3. If we are just validating the validity of a Model, checking that the ceramic.did isnā€™t really necessary as we are just loading that model and we donā€™t need to be authenticated with a DID with an appropriate DID just for loading it. Instead we should validate that the signed commits that are being applied have the appropriate CACAO (e.g. here, and here)
1 Like

#1 & #2 makes sense. Could you elaborate on #3 a bit more? So I need to verify Cacao without expiry and has proper resource as well?

And For loadModelsFromCommits and fromModels
I just need to extract cacao from each signedCommits and validate all of them ?

function validateCaco(cacao: Cacao): void {
    if (cacao.p.exp == null) {
      throw new Error(
        `only did:pkh CACAO without expiry is supported`
      )
    }
    const hasModelResource = cacao.p.resources?.includes(`ceramic://${MODEL_STREAM_ID}`)
    if (cacao.p.resources?.length != 1 || !hasModelResource) {
      throw new Error(
        `only cacao with resource ${MODEL_STREAM_ID} is supported`
      )
    }
}


async extractCapability(commit: any): Promise<Cacao | undefined> {
    if (!commit.signatures || commit.signatures.length === 0) return

    const capCID = StreamUtils.getCacaoCidFromCommit(commit)

    if (!capCID) return

    try {
      const cacao = await getCacaoFromCid(capCID)
      return cacao as Cacao
    } catch (error) {
      throw new Error(
        `Error while loading capability from IPFS with CID ${capCID.toString()}: ${error}`
      )
    }
  }

async function getCacaoFromCid(cacaoCID: string): Promise<CACAO> {
  const ipfsGateway = 'https://ipfs.io/ipfs/'
  const cacaoUrl = ipfsGateway + cacaoCID
  const res = await fetch(cacaoUrl)
  const cacaoData = await res.json()
  return cacaoData as CACAO
}

Do you mind submitting a PR? Might be easier to have the conversation over the actual code changes?

1 Like

https://github.com/ceramicstudio/js-composedb/pull/131 still WIP but is this what you were referring to by #2 and #3?