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.
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.
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?
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).
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.
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.