Skip to content

Latest commit

 

History

History
85 lines (69 loc) · 4.22 KB

README.md

File metadata and controls

85 lines (69 loc) · 4.22 KB

Minimalistic access control for Subsquid's GraphQL

Disclaimer: the code in this repository is provided purely for illustrative properties and is not in any way guaranteed to be secure by Subsquid. Only use it if you know what you're doing.

This example illustrates how basic authentication and authorization can be built into Subsquid's GraphQL server. Two users, Alice and Bob, are authenticated using JSON Web tokens and authorized to perform different root-level GraphQL selections.

The underlying data comes from a blockchain indexer, or a "squid" in Subsquid terms. It describes LiquidationCall events emitted by the AAVE V2 Lending Pool contract on Ethereum mainnet. Alice can use the full set of supported queries, while Bob can only perform liquidationEventById and squidStatus queries.

Dependencies: NodeJS, Docker, cURL.

Starting the squid

Begin by spinning up a processor, a process that ingests the data from the Ethereum Archive:

$ git clone https://github.com/subsquid-labs/access-control-example
$ cd access-control-example/
$ npm i
$ sqd build
$ sqd up # starts a Postgres database in a Docker container
$ sqd process # begins data ingestion and blocks the terminal

Then start the GraphQL server in a separate terminal:

$ sqd serve

The server begins to listen at localhost:4350. You can verify that by running:

$ curl -X POST http://localhost:4350/graphql \
-H 'Content-Type: application/json' \
-d '{"query":"query MyQuery {squidStatus{height}}"}'

The server does not allow any queries from unauthorized users, so the output should be

{"errors":[{"message":"not allowed"}]}

Tokens

The JWT tokens that Alice and Bob are signed with a symmetric secret key mySecretKey using the HS256 algirithm. The only information they encode are the names of the users stored in the standard "sub" field:

{"sub": "Alice"} -> eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJBbGljZSJ9.3r0K4FQQY_ghhPp48USw1gJQs1WbaPNt3BCv2EaNnlY
{"sub": "Bob"} -> eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJCb2IifQ.xdRJEld71Xx7RRn_fHzErShIqMx9Gf1cAV2al1FBH24

Testing authorization

Alice can perform any queries. For example, a liquidationEvents query:

$ curl -X POST http://localhost:4350/graphql \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJBbGljZSJ9.3r0K4FQQY_ghhPp48USw1gJQs1WbaPNt3BCv2EaNnlY' \
-d '{"query":"query MyQuery {liquidationEvents(limit: 3) {liquidator user}}"}'

will return a list of events:

{"data":{"liquidationEvents":[{"liquidator":"0x7a512A3Cf68df453eC76D487E3eaFFECD74d6887","user":"0xA53Fe221Bd861F75907d8Fd496DB1c70779721aA"},{"liquidator":"0x08B5cAbC97B3e4fEF88d8f2Ccb0442a669E052f8","user":"0x9A90AFFD5Fd50561A98a6Fb4358F941a131Ac592"},{"liquidator":"0x7a512A3Cf68df453eC76D487E3eaFFECD74d6887","user":"0x9A90AFFD5Fd50561A98a6Fb4358F941a131Ac592"}]}}

Bob cannot perform liquidationEvents queries. A request

$ curl -X POST http://localhost:4350/graphql \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJCb2IifQ.xdRJEld71Xx7RRn_fHzErShIqMx9Gf1cAV2al1FBH24' \
-d '{"query":"query MyQuery {liquidationEvents(limit: 3) {liquidator user}}"}'

yields

{"errors":[{"message":"not allowed"}]}

However, liquidationEventById and squidStatus queries by Bob work fine.

$ curl -X POST http://localhost:4350/graphql \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJCb2IifQ.xdRJEld71Xx7RRn_fHzErShIqMx9Gf1cAV2al1FBH24' \
-d '{"query":"query MyQuery {liquidationEventById(id:\"0011471171-000056-e8ce8\"){liquidator user} squidStatus{height}}"}'

outputs

{"data":{"liquidationEventById":{"liquidator":"0x7a512A3Cf68df453eC76D487E3eaFFECD74d6887","user":"0xA53Fe221Bd861F75907d8Fd496DB1c70779721aA"},"squidStatus":{"height":16870285}}}