hyperledger / aries-cloudagent-python

Hyperledger Aries Cloud Agent Python (ACA-Py) is a foundation for building decentralized identity applications and services running in non-mobile environments.
https://wiki.hyperledger.org/display/aries
Apache License 2.0
403 stars 510 forks source link

Error while fixing schemas and credentials definitions in wallets #2925

Open icc-garciaju opened 4 months ago

icc-garciaju commented 4 months ago

We are trying to migrate a couple of agents from indy wallets to a multitenant askar profile, as the migration tool was unable to transform MultipleWalletSingleTablet into askar-profiles.

We created a askar-profile for each agent and then added the public did they were using and set it to public.

But when we are trying to issue a credential, it returns an error:

{"exc_type": "HTTPError", "exc_message": ["400 Client Error: Issuer has no operable cred def for proposal spec {'cred_def_id': 'XXXXXXXXXXXX:3:CL:97:YYYYYY'}. for url: http://aries_cloudagent_xxx:4000/issue-credential/send"], "exc_module": "requests.exceptions"}

Then I tried to use the endpoint /credential-definition/{cred_def_id}/write_record to copy from the ledger to the walelt and I got a 500 error. I thought it could be because the schema definition wasn't on the wallet, so I tried /schemas/{schema_id}/write_record and got the same 500 error.

The trace was:

2024-05-01 10:04:51,999 aries_cloudagent.core.dispatcher ERROR Handler error: schemas_fix_schema_wallet_record
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/asyncio/tasks.py", line 256, in __step
    result = coro.send(None)
  File "/home/aries/.local/lib/python3.9/site-packages/aries_cloudagent/messaging/schemas/routes.py", line 454, in schemas_fix_schema_wallet_record
    found = await storage.find_all_records(
  File "/home/aries/.local/lib/python3.9/site-packages/aries_cloudagent/storage/askar.py", line 187, in find_all_records
    for row in await self._session.handle.fetch_all(
AttributeError: 'NoneType' object has no attribute 'fetch_all'
2024-05-01 10:04:51,999 aries_cloudagent.admin.server ERROR Handler error with exception: 'NoneType' object has no attribute 'fetch_all'

=================
Traceback (most recent call last):
  File "/home/aries/.local/lib/python3.9/site-packages/aries_cloudagent/admin/server.py", line 181, in ready_middleware
    return await handler(request)
  File "/home/aries/.local/lib/python3.9/site-packages/aries_cloudagent/admin/server.py", line 218, in debug_middleware
    return await handler(request)
  File "/home/aries/.local/lib/python3.9/site-packages/aiohttp_apispec/middlewares.py", line 45, in validation_middleware
    return await handler(request)
  File "/home/aries/.local/lib/python3.9/site-packages/aries_cloudagent/admin/server.py", line 387, in check_multitenant_authorization
    return await handler(request)
  File "/home/aries/.local/lib/python3.9/site-packages/aries_cloudagent/admin/server.py", line 450, in setup_context
    return await task
  File "/usr/local/lib/python3.9/asyncio/futures.py", line 284, in __await__
    yield self  # This tells Task to wait for completion.
  File "/usr/local/lib/python3.9/asyncio/tasks.py", line 328, in __wakeup
    future.result()
  File "/usr/local/lib/python3.9/asyncio/futures.py", line 201, in result
    raise self._exception
  File "/usr/local/lib/python3.9/asyncio/tasks.py", line 256, in __step
    result = coro.send(None)
  File "/home/aries/.local/lib/python3.9/site-packages/aries_cloudagent/messaging/schemas/routes.py", line 454, in schemas_fix_schema_wallet_record
    found = await storage.find_all_records(
  File "/home/aries/.local/lib/python3.9/site-packages/aries_cloudagent/storage/askar.py", line 187, in find_all_records
    for row in await self._session.handle.fetch_all

Then I created a schema and credential definition from the swagger api and calling the write_record endpoint returns the same error.

We're using the py3.9-0.10.5 docker image.

Thanks in advance for your help.

WadeBarnes commented 4 months ago

@dbluhm, Can you comment n this:

... as the migration tool was unable to transform MultipleWalletSingleTablet into askar-profiles.
WadeBarnes commented 4 months ago

@icc-garciaju, Are you saying you've recreated the wallets for the agents in Askar and are attempting to reuse the same schemas and cred-defs that agents were using previously, without migrating the existing records?

This will not work. The cred-def records are specific to the wallet, more specifically the cred-def record instance. It is impossible to recreate a cred-def due the fact that the keys for each cred-def are randomly generated for each cred-def (there's also the issue with attribute ordering not being guaranteed). So, if you try to generate the same cred-def, you will get a different result each time.

dbluhm commented 4 months ago

@icc-garciaju As Wade mentioned, there are secrets in the wallet that must be migrated in order to be valid and it is not possible to recreate the same object any other way. I see your issue in the aries-acapy-tools repo: https://github.com/hyperledger/aries-acapy-tools/issues/29

I can address this more on that issue but I would recommend you migrate using the mwst-as-profiles strategy. This will create a much more reasonable multitenant agent setup in the context of askar.

icc-garciaju commented 4 months ago

This will not work. The cred-def records are specific to the wallet, more specifically the cred-def record instance. It is impossible to recreate a cred-def due the fact that the keys for each cred-def are randomly generated for each cred-def (there's also the issue with attribute ordering not being guaranteed). So, if you try to generate the same cred-def, you will get a different result each time.

Thanks for the clarification.

icc-garciaju commented 4 months ago

I can address this more on that issue but I would recommend you migrate using the mwst-as-profiles strategy. This will create a much more reasonable multitenant agent setup in the context of askar.

As we are not using multitenant aca-py in our current application, mwst-as-profiles generated a different database for each source wallet even though we were using mwst. But for those two specific agents, we use DatabasePerWallet.

dbluhm commented 4 months ago

Ah, I see. The mwst-as-profiles strategy is expecting the source database to be a multitenant wallet explicitly. (Famous last words but) it doesn't seem like it would be too big of a lift to create another strategy to handle this scenario. It would be something like a mix between the mwst-as-profiles and mwst-as-stores strategies.

ianco commented 4 months ago

I'm not sure if Askar supports wallet import/export, but Indy does, so you could Export the non-multitenant Indy wallets and them import them into a multitenant instance, and then do the upgrade to Askar. (Or if Askar has the import/export support then you could do this with the Askar wallets.)

Disclaimer - I haven't tried this specifically, but I think it should work.

icc-garciaju commented 4 months ago

@ianco I didn't find the way to do it via api calls on aries-cloudagent-python, and doing it manually would be out of reach.

dbluhm commented 4 months ago

@icc-garciaju I'll try my hand at a time-boxed addition of a new strategy to the wallet upgrade tool to address this scenario. I'll report back on how far I get in that time frame.

dbluhm commented 2 months ago

Update: my time boxed new strategy attempt was overcome by other events. This should be possible and, in terms of relative complexity to other strategies implemented in the migrator, it would not be too difficult to implement. I just don't have time to do it right now. I'm happy to review a PR and offer some amount of direction.