Error: Capability does not have appropriate permissions to update this Stream

I have two issues:

  1. I cannot create a new TileDocument for a schema when using my own node due to Can not verify signature for commit ...: Capability does not have appropriate permissions to update this Stream, but this works when using https://ceramic-clay.3boxlabs.com. I’m creating a new stream, so I’m confused why the error is about updating a stream. My node is using @ceramicnetwork/cli@2.7.0.

  2. When using https://ceramic-clay.3boxlabs.com, I cannot create a new TileDocument using the schema TileDocument’s commitId as the ‘schema’:

ERROR [ExceptionsHandler] HTTP request to 'https://ceramic-clay.3boxlabs.com/api/v0/streams' failed with status 'Internal Server Error': {"error":"Can not verify signature for commit ...: Capability does not have appropriate permissions to update this Stream"}

This is how I’m authenticating:

    const addresses = await eip1193Provider.enable()
    const accountId = await getAccountId(eip1193Provider, addresses[0])
    const authMethod = await EthereumNodeAuth.getAuthMethod(eip1193Provider, accountId, 'AppName')

    const session = await DIDSession.authorize(authMethod, { resources: [ 'ceramic://' + schemaCommitId ], 'domain': process.env.CERAMIC_ORIGIN })
    
    this.ceramic.did = session.did

@zfer @ukstv any ideas how to go about debugging this?

Each time I authenticate with my wallet using DIDSession.authorize(), it returns a different did:key: for session.did.id. Is this expected?

Yes, that’s expected. The did:key is a temporary session key valid for a single user session. The stream controller should be the did:pkh with the user’s ethereum wallet address, which signs a capability granting temporary access to the session key to write data on its behalf.

I was setting the controllers as [ceramic.did.id] like the example here. I updated it to use [ceramic.did.parent], but I am experiencing the same error.

dont necessarily have to pass the controller, if you have an authenticated did attached it will handle selecting the correct did id, but yes session.id or session.did.parent would be correct to use

if your not using composedb, could you try passing resources = [ceramic://*], the wild card access to did-session, if using tiledocs, glaze, selfid wild card resource is recommended for now, more granular access will be supported in composedb

@zfer Thanks for your reply. I updated my resources to [ ‘ceramic://*’ ] and now I’m receiving this error:

Signature does not belong to issuer

I also tried creating the TileDocument with empty metadata { } instead of manually setting the controller like this:

const doc = await TileDocument.create(this.ceramic, schema, {}, { pin: true })

First I would try clearing all node_modules and lock files and reinstalling all again

Then also if you could share a full code example again with the latest changes above

any reason you are not using the glaze libraries? and using the ceramic client directly instead

I deleted node_modules and dist folders and I’m still getting the same error. I had replaced @glazed/did-session with just did-session after the suggestion in this comment.

I created an example test file and this results in the error I got in the previous thread:
Can not verify signature for commit bagcq...: Signature does not belong to issuer

import { CeramicClient } from "@ceramicnetwork/http-client"
import { TileDocument } from "@ceramicnetwork/stream-tile"
import { EthereumNodeAuth, getAccountId } from "@didtools/pkh-ethereum"
import { FireblocksWeb3Provider, ChainId } from "@fireblocks/fireblocks-web3-provider";
import { DIDSession } from "did-session"
import * as dotenv from "dotenv"
dotenv.config()

const testSchema = {
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Test Schema",
  "type": "object",
  "properties": {
    "test": { "type": "string" },
  }
}

const ceramic = new CeramicClient('https://ceramic-clay.3boxlabs.com')

const eip1193Provider = new FireblocksWeb3Provider({
  privateKey: process.env.FIREBLOCKS_API_PRIVATE_KEY_PATH,
  apiKey: process.env.FIREBLOCKS_API_KEY,
  vaultAccountIds: process.env.FIREBLOCKS_VAULT_ACCOUNT_IDS,
  chainId: ChainId.CELO_ALF,
})

const addresses = await eip1193Provider.enable()
const accountId = await getAccountId(eip1193Provider, addresses[0])
const authMethod = await EthereumNodeAuth.getAuthMethod(eip1193Provider, accountId, 'Test App')

const session = await DIDSession.authorize(authMethod, { resources: [ 'ceramic://*' ], 'domain': process.env.CERAMIC_ORIGIN })

ceramic.did = session.did

const doc = await TileDocument.create(ceramic, testSchema, {}, { pin: true })

package.json

"@ceramicnetwork/http-client": "^2.5.0",
"@didtools/pkh-ethereum": "^0.0.2",
"@fireblocks/fireblocks-web3-provider": "^0.0.8",
"did-session": "^1.0.0",

could be fireblocks/celo, probably both the first used here, seems like celo account should work if just they are just identified by chainid and standard provider, but not certain

what does the accountId as a string look like?

console.log(accountId):

AccountId {
  chainId: ChainId { namespace: 'eip155', reference: '44787' },
  address: '0x1D30F5439DABC25B32B9429dce0019E4Ad1ABfb3'
}

hmm seems fine, also cleared lock files when you reinstalled dependencies?

yeah have only seen this some mixed versions, otherwise not sure

Yes, I just tested it again making sure the lock files were removed first.

does any part of signature verification differ for celo or this provider vs eth?

This was working in a previous version of ceramic, so I don’t think it is due to any signature verification differences in Celo or the provider. However, the fireblocks provider package also had an update since then where they replaced @json-rpc-tools/provider with web3-providers-http.