Skip to content

Commit 588a687

Browse files
authored
Advanced (#238)
* upload / download page rewrite * pinning and tracking pages * add staking page * added pss page * added gsoc page * added act page draft * remove gsoc page section numbering * Added ACT and SOC / Feeds content drafts * act * ACT download section * finished SOC and feeds page draft * wording * proofread act page * Add requirements * proofreading * addressing feedback * correction
1 parent a3d9828 commit 588a687

File tree

10 files changed

+1562
-365
lines changed

10 files changed

+1562
-365
lines changed

docs/documentation/act.md

Lines changed: 360 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,368 @@ slug: /act
55
sidebar_label: ACT
66
---
77

8-
## 🚧 Under Construction 🚧
9-
:::caution 🚧 This page is under construction
8+
ACT, or Access Control Trie, is a decentralized permission system built into the Swarm network that allows you to restrict access to uploaded content.
109

11-
This section is still being worked on. Check back soon for updates!
10+
When you upload data to Swarm using ACT, only the original uploader and users with public keys listed in an associated grantee list are able to retrieve and decrypt that data. The grantee list is published separately and cryptographically referenced during upload and download operations.
1211

12+
ACT is ideal for use cases such as the serialized release of content like a podcast or newsletter where the publisher wishes to limit access to subscribers only.
13+
14+
:::warning
15+
Once a file is uploaded with ACT, any node whose public key is on the ACT grantees list referenced during the upload ***will have permanent access to that file*** as long as the file reference and history reference returned from the upload has been shared with them.
16+
17+
Updating the grantees list to remove a public key ***will not revoke access*** to the content retroactively.
18+
19+
Likewise, re-uploading the content using the new grantees list will also ***not retroactively revoke access*** to the content.
20+
:::
21+
22+
## Requirements
23+
The use of ACT requires the following:
24+
25+
* A Bee light node running on with synced postage batch data. (Running at `http://localhost:1633` by default)
26+
* A valid postage batch ID. [Buy one](/docs/storage/#purchasing-storage) if needed.
27+
* Public keys of the nodes you want to grant access to.
28+
* The **public key of the publishing node**. This can be obtained using the [`bee.getNodeAddresses()` method](/docs/status/#3-get-node-addresses).
29+
30+
## Create Grantees List
31+
32+
First we create a grantees list with the public keys of anyone we want to grant access to.
33+
34+
#### Example Script:
35+
36+
The example script below performs the following key operations:
37+
38+
1. Initializes a Bee client.
39+
2. Defines a list of grantee public keys.
40+
3. Specifies a valid postage batch ID.
41+
4. Calls `bee.createGrantees()` to create a new grantee list.
42+
5. Logs the resulting `ref` and `historyref`.
43+
44+
```js
45+
import { Bee, PublicKey, BatchId } from '@ethersphere/bee-js';
46+
47+
// Initialize Bee instance
48+
const bee = new Bee('http://localhost:1633');
49+
50+
// Grantee's public key (replace with the actual key(s) of the node(s) you wish to grant access to)
51+
const grantees = [
52+
new PublicKey('027d0c4759f689ea3dd3eb79222870671c492cb99f3fade275bcbf0ea39cd0ef6e'),
53+
];
54+
55+
// Your postage batch ID (replace with your own valid postage batch ID)
56+
const postageBatchId = new BatchId('0258a225fe8da54cc6537eb8b12fcf6706c7873dbe19b9381d31729aa0405398');
57+
58+
async function createGranteeList() {
59+
try {
60+
// Create the grantee list using `bee.createGrantees()` method
61+
const response = await bee.createGrantees(postageBatchId, grantees);
62+
63+
// Log the response (ref and history ref)
64+
console.log('Grantee List Created Successfully:');
65+
console.log('Reference:', response.ref.toHex());
66+
console.log('History Reference:', response.historyref.toHex());
67+
} catch (error) {
68+
console.error('Error creating grantee list:', error);
69+
}
70+
}
71+
72+
// Call the function to create the grantee list
73+
createGranteeList();
74+
```
75+
76+
Example output:
77+
78+
```bash
79+
Grantee List Created Successfully:
80+
Reference: 69da034fdae049eed9a22ec48b98a08ed5d363d48076f88c44ffe3367a18e306cae6aaf1cfce72d59262b9fb9293e15469c01c6a2626bb62478116cc98fb303b
81+
History Reference: 18d6f58a1d3c8253a5fc47023d49e9011236ead43724e595e898e1b422b77b19
82+
```
83+
84+
The first 64 byte (128 hex digit) reference `Grantee List Reference` (`ref`) is used on its own for reviewing the list contents and updating the list.
85+
86+
The second reference 32 byte (64 hex digit) `History Reference` (`historyref`) is used for uploading with ACT and is also used along with the first `ref` for creating a new updated grantee list based on the original list referred to by the `ref`.
87+
88+
## Update Grantees List
89+
90+
:::info
91+
Although we refer to this operation as an "update", due to Swarm's immutable nature, the original list is not modified by this operation. Rather a new list is created with the specified grantee keys added or removed from the original list. This operation ***DOES NOT*** retroactively add or remove access to content uploaded with the original ACT list.
1392
:::
1493

94+
To update a grantees list, call the `bee.patchGrantees()` method with the following arguments:
95+
96+
* A valid postage batch ID
97+
* The original list’s `ref` and `historyref`
98+
* An object specifying public keys to `add` or `revoke`
99+
100+
```js
101+
bee.patchGrantees(postageBatchId, ref, historyref, {
102+
add: [grantee1, grantee2],
103+
revoke: [],
104+
});
105+
```
106+
107+
Calling this method returns the new list’s updated `ref` and `historyref`, which you should use for future updates or access.
108+
109+
#### Example Script:
110+
111+
The example script below performs the following key steps:
112+
113+
1. Initializes the Bee client and defines two public keys to add as grantees.
114+
2. Provides the existing grantee list’s `ref` and `historyref`, and a valid postage batch ID.
115+
3. Calls `bee.patchGrantees()` to add the new keys to the list.
116+
4. Logs the updated grantee list’s `ref` and `historyref`.
117+
118+
```js
119+
import { Bee, PublicKey, BatchId, Reference } from '@ethersphere/bee-js';
120+
121+
// Initialize Bee instance
122+
const bee = new Bee('http://localhost:1633');
123+
124+
// Grantee's public key(s) to be added (replace with the actual key)
125+
const grantee1 = new PublicKey('027d0c4759f689ea3dd3eb79222870671c492cb99f3fade275bcbf0ea39cd0ef6e');
126+
const grantee2 = new PublicKey('03636056d1e08f100c5acaf14d10070102de9444c97b2e8215305ab3e97254ede6');
127+
128+
// Grantee list reference and history reference returned from initial list creation
129+
const granteeListRef = new Reference('69da034fdae049eed9a22ec48b98a08ed5d363d48076f88c44ffe3367a18e306cae6aaf1cfce72d59262b9fb9293e15469c01c6a2626bb62478116cc98fb303b')
130+
const granteeHistoryRef = new Reference('18d6f58a1d3c8253a5fc47023d49e9011236ead43724e595e898e1b422b77b19')
131+
132+
// Your postage batch ID (replace with a valid one)
133+
const postageBatchId = new BatchId('0258a225fe8da54cc6537eb8b12fcf6706c7873dbe19b9381d31729aa0405398');
134+
135+
// Function to update the grantee list by adding the new public key
136+
async function updateGranteeList() {
137+
try {
138+
// Call the patchGrantees function to add the new public key
139+
const response = await bee.patchGrantees(postageBatchId, granteeListRef, granteeHistoryRef, {
140+
add: [grantee1, grantee2], // Add the new grantee
141+
revoke: [],
142+
});
143+
144+
// Log the updated grantee list references
145+
console.log('Grantee List Updated Successfully:');
146+
console.log('Updated Reference:', response.ref.toHex());
147+
console.log('Updated History Reference:', response.historyref.toHex());
148+
} catch (error) {
149+
console.error('Error updating grantee list:', error.message);
150+
if (error.response) {
151+
// If there's an error, log the full response for more details
152+
console.error('Response Status:', error.response.status);
153+
console.error('Response Body:', JSON.stringify(error.response.body, null, 2));
154+
}
155+
}
156+
}
157+
158+
// Call the function to update the grantee list
159+
updateGranteeList();
160+
```
161+
162+
Example output:
163+
164+
```bash
165+
Grantee List Updated Successfully:
166+
Updated Reference: a029324c42e7911032b83155f487d545b6e07b521a90fce90a266f308c0a455417e71bc03621868da2f6e84357ba772cb03b408fce79862b03d2e082004eccd8
167+
Updated History Reference: d904f0790acb7edfda6a078176d64ec026b40298bfdbceb82956533e31489fcd
168+
```
169+
170+
## Get Grantees List
171+
172+
In order to view the members of our grantees list we need to use the 64 byte `ref` returned when we create or update a list. We will view both our original list and the updated list based on the original list using the respective `ref` from each list:
173+
174+
:::info
175+
The grantee list is encrypted, and only the owner can view the grantee list, make sure to use the owner node when using the `bee.getGrantees()` method.
176+
:::
177+
178+
#### Example Script:
179+
180+
The example script below performs the following operations:
181+
182+
1. Initializes a Bee client.
183+
2. Defines two existing grantee list 64 byte `ref` copied from the results of our previous example scripts.
184+
3. Calls `bee.getGrantees()` for each `ref` to retrieve the corresponding grantee list.
185+
4. Logs the status, status text, and list of grantee public keys in compressed hex format.
186+
187+
188+
```js
189+
import { Bee, Reference } from '@ethersphere/bee-js';
190+
191+
// Initialize Bee instance
192+
const bee = new Bee('http://localhost:1633');
193+
194+
195+
// Grantee list references (the reference returned from the `bee.createGrantees()` function)
196+
const granteeListRef_01 = new Reference('69da034fdae049eed9a22ec48b98a08ed5d363d48076f88c44ffe3367a18e306cae6aaf1cfce72d59262b9fb9293e15469c01c6a2626bb62478116cc98fb303b');
197+
const granteeListRef_02 = new Reference('a029324c42e7911032b83155f487d545b6e07b521a90fce90a266f308c0a455417e71bc03621868da2f6e84357ba772cb03b408fce79862b03d2e082004eccd8');
198+
199+
// Function to get the grantee list
200+
async function getGranteeList(granteeListRef) {
201+
try {
202+
// Call the getGrantees function with the reference
203+
const result = await bee.getGrantees(granteeListRef);
204+
205+
// Log the full response
206+
console.log('Grantee List Retrieved:');
207+
console.log('Status:', result.status);
208+
console.log('Status Text:', result.statusText);
209+
210+
// Log the grantee lists as arrays of their hex string representations
211+
console.log('Grantees:', result.grantees.map(grantee => grantee.toCompressedHex()));
212+
213+
} catch (error) {
214+
console.error('Error retrieving grantee list:', error);
215+
}
216+
}
217+
218+
// Call the function to fetch the grantee list
219+
getGranteeList(granteeListRef_01);
220+
getGranteeList(granteeListRef_02);
221+
```
222+
223+
Example output:
224+
225+
```bash
226+
Grantee List Retrieved:
227+
Status: 200
228+
Status Text: OK
229+
Grantees: [
230+
'027d0c4759f689ea3dd3eb79222870671c492cb99f3fade275bcbf0ea39cd0ef6e'
231+
]
232+
Grantee List Retrieved:
233+
Status: 200
234+
Status Text: OK
235+
Grantees: [
236+
'027d0c4759f689ea3dd3eb79222870671c492cb99f3fade275bcbf0ea39cd0ef6e',
237+
'03636056d1e08f100c5acaf14d10070102de9444c97b2e8215305ab3e97254ede6'
238+
]
239+
```
240+
241+
The first list of grantees contains the first public key we gave access to when we created the list, while the second one contains both the first and the second one we added when we created our second list based on the first one.
242+
243+
## Upload With ACT
244+
245+
We can upload our content with either of the two lists we created depending on which set of users we wish to give access too. In the example below, we use both lists.
246+
247+
#### Example Script:
248+
249+
The example script below performs the following operations:
250+
251+
1. Initializes a Bee client.
252+
2. Defines a postage batch ID and two ACT grantee list 32 byte `historyref` hashes returned from the operations in the previous examples.
253+
3. Defines a string to upload as a sample file.
254+
4. Calls `bee.uploadFile()` twice with ACT enabled, specifying a `historyRef` each time to enforce access control.
255+
5. Logs the resulting Swarm reference and history reference after each upload.
256+
257+
```js
258+
import { Bee, BatchId, Reference } from '@ethersphere/bee-js';
259+
260+
// Initialize Bee instance
261+
const bee = new Bee('http://localhost:1633');
262+
263+
// Your postage batch ID (replace with a valid one)
264+
const postageBatchId = new BatchId('0258a225fe8da54cc6537eb8b12fcf6706c7873dbe19b9381d31729aa0405398');
265+
266+
// Grantee list reference (the reference returned from the `bee.createGrantees()` function)
267+
const historyRef_01 = new Reference('18d6f58a1d3c8253a5fc47023d49e9011236ead43724e595e898e1b422b77b19');
268+
const historyRef_02 = new Reference('d904f0790acb7edfda6a078176d64ec026b40298bfdbceb82956533e31489fcd');
269+
270+
// Sample data to upload
271+
const fileData = 'This is a sample string that will be uploaded securely using ACT.';
272+
273+
274+
async function uploadWithACT(historyRef) {
275+
try {
276+
// Upload the string with ACT enabled
277+
const result = await bee.uploadFile(postageBatchId, fileData, 'samplefile.txt', {
278+
act: true, // Enable ACT for the uploaded data
279+
actHistoryAddress: historyRef, // Provide the grantee list reference for ACT
280+
contentType: 'text/plain',
281+
});
282+
283+
console.log('File uploaded successfully with ACT:');
284+
console.log('Reference:', result.reference.toHex());
285+
console.log("History reference")
286+
console.log(result.historyAddress.value.toHex())
287+
} catch (error) {
288+
console.error('Error uploading file with ACT:', error);
289+
}
290+
}
291+
292+
// Call the function to upload the file with each `historyref`
293+
uploadWithACT(historyRef_01);
294+
uploadWithACT(historyRef_02);
295+
```
296+
297+
Example output:
298+
299+
```bash
300+
File uploaded successfully with ACT:
301+
Reference: e227acea84e1d55e90baa93a698e79577a5b1c54513925b61476386798b41728
302+
History reference
303+
18d6f58a1d3c8253a5fc47023d49e9011236ead43724e595e898e1b422b77b19
304+
File uploaded successfully with ACT:
305+
Reference: e227acea84e1d55e90baa93a698e79577a5b1c54513925b61476386798b41728
306+
History reference
307+
d904f0790acb7edfda6a078176d64ec026b40298bfdbceb82956533e31489fcd
308+
```
309+
310+
The reference hash is the same for each upload since the content is the same. The reference hash along with a `historyref` and the uploader's public key are required in order to access the content uploaded with ACT.
311+
312+
You can choose which `historyref` to share depending on which set of public keys you wish to authorize to download the content.
313+
314+
## Download With ACT
315+
316+
In order to download using ACT, we must pass in the public key from the grantee list creator along with the file reference and history reference returned from the file upload operation:
317+
318+
#### Example Script:
319+
320+
The example script below performs the following operations:
321+
322+
1. Initializes a Bee client.
323+
2. Defines a publisher public key and associated file reference + history references for ACT-protected content using the references returned from the upload operation.
324+
3. Calls `bee.downloadFile()` with ACT options (`actPublisher` and `actHistoryAddress`) to access protected data.
325+
4. Logs the decoded file content.
326+
327+
328+
```js
329+
import { Bee, Reference, PublicKey } from '@ethersphere/bee-js'
330+
331+
// Initialize Bee instance
332+
const bee = new Bee('http://localhost:1633')
333+
334+
335+
// Publisher public key used during upload
336+
const publisherPublicKey = new PublicKey('0295562f9c1013d1db29f7aaa0c997c4bb3f1fc053bd0ed49a3d98584490cc8f96');
337+
338+
// File reference and history reference returned from upload operation
339+
const fileRef_01 = new Reference('e227acea84e1d55e90baa93a698e79577a5b1c54513925b61476386798b41728');
340+
const historyRef_01 = new Reference('18d6f58a1d3c8253a5fc47023d49e9011236ead43724e595e898e1b422b77b19');
341+
342+
343+
// Function to download ACT-protected content
344+
async function downloadWithACT(fileRef, historyRef, publisherPubKey) {
345+
try {
346+
const result = await bee.downloadFile(fileRef, './', {
347+
actPublisher: publisherPubKey,
348+
actHistoryAddress: historyRef
349+
})
350+
351+
console.log('Content:', result.data.toUtf8())
352+
} catch (error) {
353+
console.error(`Error downloading from reference ${fileRef}:`, error)
354+
}
355+
}
356+
357+
downloadWithACT(
358+
fileRef_01,
359+
historyRef_01,
360+
publisherPublicKey
361+
)
362+
```
363+
364+
Example terminal output:
365+
366+
```bash
367+
Content: This is a sample string that will be uploaded securely using ACT.
368+
```
369+
370+
In the example above, we used the history reference from the file uploaded using the grantees list with only one public key included (`027d0c4759f689ea3dd3eb79222870671c492cb99f3fade275bcbf0ea39cd0ef6e`), and so it will only be able to be retrieved and decrypted by the node with that public key.
15371

16-
* Show example of creating grantee list
17-
* Show example of secure upload
18-
* Show example of secure download
372+
If any other node attempts to download this content then a 404 error will be returned.

0 commit comments

Comments
 (0)