Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Communication concept api.metaanchor.io #7

Closed
pedrolucasp opened this issue Sep 1, 2023 · 3 comments
Closed

Communication concept api.metaanchor.io #7

pedrolucasp opened this issue Sep 1, 2023 · 3 comments
Assignees
Labels
documentation Improvements or additions to documentation

Comments

@pedrolucasp
Copy link
Collaborator

In order to make it clear since both projects are distinct parts of the same ecosystem but different applications and each has an API/backend itself I'll call api.metaanchor.io as API and this project as a metaanchor instance, whether is backend or frontend.


In order to authenticate a metaanchor instance and make sure that it can call the API, it should have some means to authenticate itself and do the whole auto-setup of the API. This basically gives the API a way to do sanity-checking and health checks on the instance and it unlocks the instance to read and push information to the API. The workflow right now, from a customer point of view, is to register for a DevKit, grab the JSON (containing the API Key), and upload it to their instance so it can freely communicate with the API.

Right now, when signing up for a DevKit, the user must register where is their instance located. Thinking in terms of a multi-tenant or single tenant, they should simply place where their instance is running, and the DevKit sign-up form should simply present their API and any other relevant information. From that point forward, as long as the instance has this copy of the API it can "call home" and register that instance.

Now, I see two potential ways to do it:

(1) Most likely we don't need multiple API Keys for the same instance. Since the instance can simply communicate using the same API Key to the API servers, and inform with the data it carries which tenant is doing what action/operation (using their wallet for instance). The whole setup can be a one-time thing that the instance owner would have to do before other users hop on. In other words, an instance would have an API Key aggregating multiple users.

(2) Each user would be obligated to do the whole setup every time, and the application would have to do the job of picking which API Key to use to communicate with the API; the API Server would use the API Key to figure it out who's talking to them. This can be useful for sending back information to the API, but the other way around would be a bit problematic since the API would have to pick which API Key to use to communicate back with the instance, etc.

@pedrolucasp pedrolucasp changed the title Grabbing metaanchor's API Key Communicating with the api.metaanchor.io Sep 1, 2023
@tbergmueller
Copy link
Member

tbergmueller commented Sep 1, 2023

I'd rather favor an approach similar to (1), where each instance has 1 API-Key. Going with api.metaanchor.io as API and this github-repository as INSTANCE. Further using OWNER as the person who owns the smart contract and orders e.g. the MetaAnchor DevKit.

I'd propose the following setup process for Single-Tenant;

(ST1) OWNER fills out the order-form on https://metaanchor.io and lists 0x123...abc as the owner-wallet of a DigitalSoul-NFT contract identified by csn=UFCJ
(ST2) API creates an API-Key api_key=metaanchor_xyz for 0x123...abc and recognizes that 0x123..abc will at some point register a new INSTANCE. It also recognizes that this then-registered instance will correspond to the smart contract identified via csn=UFCJ
(ST3) OWNER receives instructions, downloads and installs INSTANCE and starts setup.
(ST4) Setup and key-sharing protocol
-- (ST4.1) During setup, OWNER is asked to sign a message "Welcome to MetaAnchor-API" with his wallet 0x123...abc. We denote this message+signature string as SIGNED_WELCOME_MESSAGE
-- (ST4.2) INSTANCE generates an instance_api_key="SUPERSECRET", which is used by api.metaanchor.io to authorize itself to call the /push/ endpoints of the INSTANCE (refer #8)
-- (ST4.3) Setup of INSTANCE calls API, e.g. POST https://api.metaanchor.io/api/v1/register (which is open for all*) with the following payload: POST_DATA={"instance_api_key":"SUPERSECRET", "registrar": "0x123..abc", "authorization": "SIGNED_WELCOME_MESSAGE", ... additional info on reachability, versions etc ... }.
-- (ST4.4) API verifies that POST_DATA.registrar is allowed to register a new instance (otherwise returns 401) and that indeed registrar is sending the request by verifying whether signer(POST_DATA.authorization) == POST_DATA.registrar
-- (ST4.5) API stores details about INSTANCE (how to reach API, how to reach FRONTEND, ...) together with POST_DATA.instance_api_key
-- (ST4.6) Upon successful verification, API returns RESPONSE_DATA={"api_key": "metaanchor_xyz"}.
-- (ST4.7) INSTANCE stores RESPONSE_DATA.api_key and uses it for all subsequent communication with API
(ST5) INSTANCE may complete setup by copying files, starting services etc.
(ST6) Complete Registration
-- (ST6.1) INSTANCE calls API to signal successful setup via GET [Authorization Bearer api_key] https://api.metaanchor.io/api/v1/register/complete
-- (ST6.2) API tests GET [Authorization Bearer instance_api_key] INSTANCE/push/hello (#8) and possibly other push endpoints, status-endpoints, Frontend-reachability etc
-- (ST6.3) API returns {"success": True/False}, depending on the results of (ST6.2)
(ST7) API may start pushing information to INSTANCE, such as SLID<>ANCHOR-Pairs of all SLIDs supported by the contract csn=UFCJ etc, refer #8

  • Some level of spam-protection for the API/register endpoint may make sense, e.g. adding a certificate or Static-API-Key or adding a pre-shared installation code may make sense. For simplicity in the first step, let's go with open-for-all.

Multi-Tenant:
TODO once we have a first iteration on the one above.

@tbergmueller
Copy link
Member

tbergmueller commented Sep 20, 2023

Sligthly adapting the one above by splitting into "register instance" and "claim contract", which are essentially independently.

An INSTANCE only needs to be registered once (by any contract OWNER). For each contract, the contract owner has to log in at the INSTANCE and register the contract to the INSTANCE.

Specs INSTANCE registration (#9 )

  • Each INSTANCE has one api_key, with which it authenticates itself towards API
  • Each INSTANCE issues one instance_api_key, with which API authenticates itself towards INSTANCE (/push/ endpoint #8 )

Specs Contract Claim (#10 )

  • Each INSTANCE "manages" 1...N contracts
  • An INSTANCE claims to manage a specific contract by the owner signing authorization = signature("I own csn=<CSN>"), with <CSN> being the contract short name, e.g. UFCJ. We then call https://api.metaanchor.io/api/v1/contract/UFCJ/claim through INSTANCE with the payload { "authorization": signature("I own csn=<CSN>").
    • This claims the specific contract identified through CSN to the INSTANCE via the api_key that has been used.
    • After a successful claim, API may start pushing data for the specific CSN to INSTANCE.
  • If a contract owner registers his contract through a different INSTANCE, the previous active instance looses all permissions to manage the contract.
  • The data in the previous active instance is not deleted!

Example

ma_api_communication

In the present example, we have 3 smart contracts identified by CSNs UFCJ, RDFC and MACO. RDFC and MACO are incidentially have the same OWNER. There are two spawned DigitalSoul-INSTANCEs A and B

Communications leading to that configuration:

  1. Instances A and B where registered already through DigitalSoul Instance Registration #9 (either by OWNER 0x3b7e or OWNER 0xa7e).
  2. At some point, the OWNER 0xa7e2 has logged in to INSTANCE A and claimed (via Contract Claim #10 ) contract RDFC there. This means a call with INSTANCE_A's api_key=metaanchor_4BnRTOX and the payload {"csn": "RDFC", "authorization": signature("I claim csn=RDFC")
  3. At another point, the OWNER 0xa7e has logged into INSTANCE B and claimed (via Contract Claim #10) contract MACO there.
  4. Lastly, OWNER 0x3b7e has logged into INSTANCE B and claimed (via Contract Claim #10) the contract UFCJ there.

edited
examples to match api.metaanchor.io v0.2.0 and higher~

@tbergmueller tbergmueller changed the title Communicating with the api.metaanchor.io Communication concept api.metaanchor.io Sep 20, 2023
@tbergmueller tbergmueller self-assigned this Sep 20, 2023
@tbergmueller tbergmueller added the documentation Improvements or additions to documentation label Sep 20, 2023
@tbergmueller
Copy link
Member

Will close this, as follow-up tickets #9 and #10 for implementation were created. This ticket serves as documentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

2 participants