# Block level access control

**URL:** <https://discuss.ipfs.tech/t/block-level-access-control/13326>\
**Category:** Ecosystem and Usage\
**Tags:** peergos, bitswap\
**Created:** [January 31, 2022, 3:04pm UTC](https://discuss.ipfs.tech/t/block-level-access-control/13326 "2022-01-31T15:04:58Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![ianopolous](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/ianopolous/32/386_2.png) [@ianopolous](https://discuss.ipfs.tech/u/ianopolous)\
**Post date:** [January 31, 2022, 3:04pm UTC](https://discuss.ipfs.tech/t/block-level-access-control/13326/1 "2022-01-31T15:04:58Z")

</div>

We’ve just released a ground-breaking new access control mechanism for blocks in IPFS which is post-quantum, capability-based, auto-scaling and fine grained. This involved extending the bitswap protocol to allow an optional auth byte array with every cid requested. This is in addition to our existing access control based on the encryption properties of our extended cryptree design.

You can read more about it here:  
[https://peergos.org/posts/bats](https://peergos.org/posts/bats)

---

<div class="post-metadata">

**Author:** ![hsn10](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/hsn10/32/3711_2.png) [@hsn10](https://discuss.ipfs.tech/u/hsn10)\
**Post date:** [February 2, 2022, 12:22pm UTC](https://discuss.ipfs.tech/t/block-level-access-control/13326/2 "2022-02-02T12:22:44Z")

</div>

if something is requested by this extension. Will it be password protected also on new node sharing cached data? How will another node check if password is correct without common access database?

---

<div class="post-metadata">

**Author:** ![ianopolous](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/ianopolous/32/386_2.png) [@ianopolous](https://discuss.ipfs.tech/u/ianopolous)\
**Post date:** [February 2, 2022, 1:20pm UTC](https://discuss.ipfs.tech/t/block-level-access-control/13326/3 "2022-02-02T13:20:10Z")

</div>

The block level access control is independent of the encryption in the block itself. In Peergos all blocks are encrypted. A read capability to a file includes a BAT and a decryption key you can both retrieve the blocks for it and decrypt them.

Because the BAT for a block is derived from the block itself any new node which has retrieved a block can (and does) enforce the same access control for incoming bitswap requests without any extra information or database.

---

<div class="post-metadata">

**Author:** ![Akita](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/akita/32/2650_2.png) [@Akita](https://discuss.ipfs.tech/u/Akita)\
**Post date:** [February 2, 2022, 3:01pm UTC](https://discuss.ipfs.tech/t/block-level-access-control/13326/4 "2022-02-02T15:01:57Z")

</div>

@ianopolous Have you had contact with PL about this? Are they interested in spec’ing it and implementing it in vanilla IPFS?

---

<div class="post-metadata">

**Author:** ![ianopolous](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/ianopolous/32/386_2.png) [@ianopolous](https://discuss.ipfs.tech/u/ianopolous)\
**Post date:** [February 2, 2022, 4:00pm UTC](https://discuss.ipfs.tech/t/block-level-access-control/13326/5 "2022-02-02T16:00:02Z")

</div>

@Akita yes I discussed the design with the ipfs lead during development.

This is our auth extension to bitswap:

> **[GitHub - Peergos/go-bitswap-auth](https://github.com/peergos/go-bitswap-auth)**
>
> Contribute to Peergos/go-bitswap-auth development by creating an account on GitHub.

It’s included in our ipfs replacement:

> **[GitHub - Peergos/ipfs-nucleus: A minimal IPFS replacement for P2P IPLD apps](https://github.com/peergos/ipfs-nucleus/)**
>
> A minimal IPFS replacement for P2P IPLD apps. Contribute to Peergos/ipfs-nucleus development by creating an account on GitHub.

and we’ve submitted a proposal to upstream it:

> <https://github.com/ipfs/specs/issues/260>
>
> I'd like to propose an optional extension to bitswap for requiring authorisation… to retrieve a block. We've already implemented this and integrated it in Peergos. 
> 
> The proposal is to add optional auth byte\[\] to wants, blocks and block presence. Our updated protobuf is here - 
> https://github.com/Peergos/go-bitswap-auth/blob/master/message/pb/message.proto
> 
> The repo where we've implemented this is: https://github.com/peergos/go-bitswap-auth
> Trying to directly upstream our code there probably doesn't make sense because of the changes we've made to some external interfaces, but if it does then we can consider relicensing it from AGPL in that situation. 
> 
> We use this in Peergos (via \[ipfs-nucleus\](https://github.com/peergos/ipfs-nucleus/)) to implement a post-quantum capability based auth scheme using S3 V4 signatures. You can read more about our design here: https://github.com/Peergos/Peergos/pull/884 here: https://github.com/Peergos/Peergos/issues/862 and here: https://peergos.org/posts/bats
> 
> On the bitswap level the motivation is the following: We wanted to add block level authorisation to retrieve each block. This means a different auth is required to be sent with each want request. In our usage the auth ended up being 89 bytes, but we haven't limited the size other than the pre-existing bitswap message size. When a block is returned you also need to return the auth string so the sender knows which want request was allowed in case of multiple concurrent want requests with different auth for the same cid. Similar reasoning applies to the BlockPresence message (we don't want to automatically expose the presence of a block). 
> 
> In our usage the auth string is tied to the sender's peer ID so it doesn't matter that the auth string is being broadcast to the DHT. Clearly any other designs based on this will need the same property.

---

<div class="post-metadata">

**Author:** ![zacharywhitley](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/zacharywhitley/32/2670_2.png) [@zacharywhitley](https://discuss.ipfs.tech/u/zacharywhitley)\
**Post date:** [February 3, 2022, 4:27pm UTC](https://discuss.ipfs.tech/t/block-level-access-control/13326/6 "2022-02-03T16:27:20Z")

</div>

So if I understand this correctly this is a best effort at limiting the distribution of blocks to certain PeerID’s? There’s nothing stopping me from deploying a client that strips the BAT’s off and reproves them given that I’m authorized and can get them in the first place, correct?

---

<div class="post-metadata">

**Author:** ![ianopolous](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/ianopolous/32/386_2.png) [@ianopolous](https://discuss.ipfs.tech/u/ianopolous)\
**Post date:** [February 3, 2022, 4:41pm UTC](https://discuss.ipfs.tech/t/block-level-access-control/13326/7 "2022-02-03T16:41:32Z")

</div>

It’s not tied to certain peerIDs. It is a pure capability system - if you have the BAT and CID for a block then you can retrieve it. As with any secret sharing system, whether it’s Signal or whatever, if you share a secret with someone and they then maliciously share it onwards against your wishes there is nothing you can do about that. That is fundamental property of information.

Also, If you remove the BATs from a block, then you change the block and thus it has a different CID, so it won’t be reachable or discoverable via the original CID. It is impossible to retrieve a private block without first obtaining the authorisation to retrieve it (the BAT and CID).

---

<div class="post-metadata">

**Author:** ![zacharywhitley](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/zacharywhitley/32/2670_2.png) [@zacharywhitley](https://discuss.ipfs.tech/u/zacharywhitley)\
**Post date:** [February 3, 2022, 4:49pm UTC](https://discuss.ipfs.tech/t/block-level-access-control/13326/8 "2022-02-03T16:49:30Z")

</div>

I meant it’s tied to the PeerID as in that’s what is being authorized. I wasn’t sure where the BAT was stored and if that would effect the CID but that answers another question I had. Thanks.

---

<div class="post-metadata">

**Author:** ![ianopolous](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/ianopolous/32/386_2.png) [@ianopolous](https://discuss.ipfs.tech/u/ianopolous)\
**Post date:** [February 3, 2022, 4:56pm UTC](https://discuss.ipfs.tech/t/block-level-access-control/13326/9 "2022-02-03T16:56:47Z")

</div>

A BAT is not tied to anything it’s just 32 random bytes. A particular auth string derived from a BAT (in our usage with S3 V4 signatures) at a particular time, to retrieve a block, is tied to the time, expiry, cid and source node Id.

---

<div class="post-metadata">

**Author:** ![zacharywhitley](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/zacharywhitley/32/2670_2.png) [@zacharywhitley](https://discuss.ipfs.tech/u/zacharywhitley)\
**Post date:** [February 3, 2022, 5:06pm UTC](https://discuss.ipfs.tech/t/block-level-access-control/13326/10 "2022-02-03T17:06:37Z")

</div>

Sorry to keep hitting you with questions but I’m genuinely interested in how it works. How is the auth string derived?

---

<div class="post-metadata">

**Author:** ![ianopolous](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/ianopolous/32/386_2.png) [@ianopolous](https://discuss.ipfs.tech/u/ianopolous)\
**Post date:** [February 3, 2022, 5:16pm UTC](https://discuss.ipfs.tech/t/block-level-access-control/13326/11 "2022-02-03T17:16:05Z")

</div>

Not at all! Questions are great. The auth string is essentially timestamp + expiry + signature, where the signature is an S3 V4 signature (the same auth that S3 uses). The URL to sign in this case is basically:

GET sourceNodeID/api/v0/block/get?arg=$CID with expiry and time included as signed headers.

There a link to the S3 V4 signature scheme in the blog post - it’s a standard.
