Installation
Install Bao with the right tool for your programming language.
pip install baolib
go get github.com/stregato/bao/lib
dart pub add bao
dart run bao:bootstrap
# Add to pom.xml or build.gradle
# Dependency details available on Maven Central
Basic Example: File Sharing
Alice and Bob want to share files securely. Here’s how it works step by step.
Step 1: Create Identities
Each person generates a private/public key pair to secure their communications.
from baolib import *
# Alice creates her identity
alice, alice_secret = newKeyPair()
print(f"Alice's public ID: {alice}")
# Bob creates his identity
bob, bob_secret = newKeyPair()
print(f"Bob's public ID: {bob}")
package main
import (
"fmt"
"github.com/stregato/bao/lib"
)
func main() {
// Alice creates her identity
alice, aliceSecret := lib.NewKeyPair()
fmt.Println("Alice's public ID:", alice)
// Bob creates his identity
bob, bobSecret := lib.NewKeyPair()
fmt.Println("Bob's public ID:", bob)
}
import 'package:bao/bao.dart';
void main() {
// Alice creates her identity
final (alice, aliceSecret) = newKeyPair();
print('Alice public ID: $alice');
// Bob creates his identity
final (bob, bobSecret) = newKeyPair();
print('Bob public ID: $bob');
}
import ink.francesco.bao.*;
public class QuickStart {
public static void main(String[] args) {
// Alice creates her identity
var aliceKeyPair = IDs.newKeyPair();
var alice = aliceKeyPair.publicID();
var aliceSecret = aliceKeyPair.privateID();
System.out.println("Alice's public ID: " + alice);
// Bob creates his identity
var bobKeyPair = IDs.newKeyPair();
var bob = bobKeyPair.publicID();
var bobSecret = bobKeyPair.privateID();
System.out.println("Bob's public ID: " + bob);
}
}
Step 2: Alice’s Side - Create Vault and Write
Alice sets up storage, creates a vault, grants Bob access, and writes a file.
from baolib import *
from pathlib import Path
import tempfile
# Configure cloud storage
store = Store(s3_store(
id='my-vault',
endpoint='s3.amazonaws.com',
bucket='my-bucket',
access_key_id='your-key-id',
secret_access_key='your-secret',
prefix='bao'
))
# Create a database for Alice's vault
db_alice = DB('sqlite3', 'alice_vault.db')
# Alice creates a vault (she already has alice and alice_secret from Step 1)
vault_alice = Vault.create(alice_secret, store, db_alice)
# Alice grants Bob access to her vault
vault_alice.sync_access([AccessChange(bob, Access.read_write)])
print("Bob now has access to Alice's vault")
# Alice creates a file to share
tmp_file = Path(tempfile.mkdtemp()) / "message.txt"
tmp_file.write_text("Hello Bob! This is Alice.")
# Alice writes the file to the vault
file_info = vault_alice.write('shared/message.txt', src=str(tmp_file))
vault_alice.wait_files([file_info.id])
print(f"File written: {file_info.name}")
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/stregato/bao/lib"
"github.com/stregato/bao/lib/store"
"github.com/stregato/bao/lib/vault"
)
func main() {
// Configure cloud storage
storeCfg := store.StoreConfig{
Type: "s3",
Id: "my-vault",
S3: store.S3Config{
Bucket: "my-bucket",
Endpoint: "s3.amazonaws.com",
Prefix: "bao",
Auth: store.S3ConfigAuth{
AccessKeyId: "your-key-id",
SecretAccessKey: "your-secret",
},
},
}
store, err := store.Open(storeCfg)
if err != nil {
panic(err)
}
// Create a database for Alice's vault
dbAlice, err := lib.OpenDB("sqlite3", "alice_vault.db", "")
if err != nil {
panic(err)
}
// Alice creates a vault (she already has alice and aliceSecret from Step 1)
vaultAlice, err := vault.Create(aliceSecret, store, dbAlice, vault.Config{})
if err != nil {
panic(err)
}
// Alice grants Bob access to her vault
err = vaultAlice.SyncAccess(vault.IOOption{}, vault.AccessChange{
UserId: bob,
Access: vault.ReadWrite,
})
if err != nil {
panic(err)
}
fmt.Println("Bob now has access to Alice's vault")
// Alice creates a file to share
tmpDir := os.TempDir()
tmpFile := filepath.Join(tmpDir, "message.txt")
err = os.WriteFile(tmpFile, []byte("Hello Bob! This is Alice."), 0o600)
if err != nil {
panic(err)
}
// Alice writes the file to the vault
fileInfo, err := vaultAlice.Write("shared/message.txt", tmpFile, nil, vault.IOOption{})
if err != nil {
panic(err)
}
fmt.Println("File written:", fileInfo.Name)
}
import 'dart:io';
import 'package:bao/bao.dart';
void main() async {
// Configure cloud storage
final storeConfig = StoreConfig.s3(
id: 'my-vault',
bucket: 'my-bucket',
endpoint: 's3.amazonaws.com',
prefix: 'bao',
accessKeyId: 'your-key-id',
secretAccessKey: 'your-secret',
);
final store = await Store.open(storeConfig);
// Create a database for Alice's vault
final dbAlice = await DB.open('sqlite3', 'alice_vault.db');
// Alice creates a vault (she already has alice and aliceSecret from Step 1)
final vaultAlice = await Vault.create(
aliceSecret,
store,
dbAlice,
);
// Alice grants Bob access to her vault
await vaultAlice.syncAccess([
AccessChange(bob, accessReadWrite),
]);
print('Bob now has access to Alice\'s vault');
// Alice creates a file to share
final tmpDir = Directory.systemTemp;
final tmpFile = File('${tmpDir.path}/message.txt');
await tmpFile.writeAsString('Hello Bob! This is Alice.');
// Alice writes the file to the vault
final fileInfo = await vaultAlice.write(
'shared/message.txt',
src: tmpFile.path,
);
print('File written: ${fileInfo.name}');
}
import ink.francesco.bao.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.HashMap;
public class QuickStart {
public static void main(String[] args) throws Exception {
// Configure cloud storage
var storeConfig = StoreConfig.s3(
"my-vault",
"s3.amazonaws.com",
"us-east-1",
"my-bucket",
"bao",
"your-key-id",
"your-secret"
);
var store = Store.open(storeConfig);
// Create a database for Alice's vault
var dbAlice = new DB("alice_vault.db");
// Alice creates a vault (she already has alice and aliceSecret from Step 1)
var vaultAlice = Vault.create(
aliceSecret,
store,
dbAlice,
new HashMap<>()
);
// Alice grants Bob access to her vault
vaultAlice.syncAccess(Arrays.asList(
new Vault.AccessChange(3, bob)
));
System.out.println("Bob now has access to Alice's vault");
// Alice creates a file to share
Path tmpFile = Files.createTempFile("message", ".txt");
Files.writeString(tmpFile, "Hello Bob! This is Alice.");
// Alice writes the file to the vault
var fileInfo = vaultAlice.write("shared/message.txt", new byte[0], tmpFile.toString());
System.out.println("File written: " + fileInfo.name);
}
}
Step 3: Bob’s Side - Open Vault and Read
Bob opens Alice’s vault and reads the file she wrote.
from baolib import *
from pathlib import Path
import tempfile
# Use the same store configuration as Alice
store = Store(s3_store(
id='my-vault',
endpoint='s3.amazonaws.com',
bucket='my-bucket',
access_key_id='your-key-id',
secret_access_key='your-secret',
prefix='bao'
))
# Create a database for Bob's vault
db_bob = DB('sqlite3', 'bob_vault.db')
# Bob opens Alice's vault using Alice's public ID
# (bob and bob_secret are from Step 1, alice is Alice's public ID from Step 1)
vault_bob = Vault.open(bob_secret, alice, store, db_bob)
# Bob reads the file Alice wrote
out_file = Path(tempfile.mkdtemp()) / "received.txt"
vault_bob.read('shared/message.txt', str(out_file))
# Bob reads and displays the content
content = out_file.read_text()
print(f"Bob received: {content}")
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/stregato/bao/lib"
"github.com/stregato/bao/lib/store"
"github.com/stregato/bao/lib/vault"
)
func main() {
// Use the same store configuration as Alice
storeCfg := store.StoreConfig{
Type: "s3",
Id: "my-vault",
S3: store.S3Config{
Bucket: "my-bucket",
Endpoint: "s3.amazonaws.com",
Prefix: "bao",
Auth: store.S3ConfigAuth{
AccessKeyId: "your-key-id",
SecretAccessKey: "your-secret",
},
},
}
store, err := store.Open(storeCfg)
if err != nil {
panic(err)
}
// Create a database for Bob's vault
dbBob, err := lib.OpenDB("sqlite3", "bob_vault.db", "")
if err != nil {
panic(err)
}
// Bob opens Alice's vault using Alice's public ID
// (bob and bobSecret are from Step 1, alice is Alice's public ID from Step 1)
vaultBob, err := vault.Open(bobSecret, alice, store, dbBob)
if err != nil {
panic(err)
}
// Bob reads the file Alice wrote
tmpDir := os.TempDir()
outFile := filepath.Join(tmpDir, "received.txt")
_, err = vaultBob.Read("shared/message.txt", outFile, vault.IOOption{}, nil)
if err != nil {
panic(err)
}
// Bob reads and displays the content
content, err := os.ReadFile(outFile)
if err != nil {
panic(err)
}
fmt.Println("Bob received:", string(content))
}
import 'dart:io';
import 'package:bao/bao.dart';
void main() async {
// Use the same store configuration as Alice
final storeConfig = StoreConfig.s3(
id: 'my-vault',
bucket: 'my-bucket',
endpoint: 's3.amazonaws.com',
prefix: 'bao',
accessKeyId: 'your-key-id',
secretAccessKey: 'your-secret',
);
final store = await Store.open(storeConfig);
// Create a database for Bob's vault
final dbBob = await DB.open('sqlite3', 'bob_vault.db');
// Bob opens Alice's vault using Alice's public ID
// (bob and bobSecret are from Step 1, alice is Alice's public ID from Step 1)
final vaultBob = await Vault.open(
bobSecret,
alice,
store,
dbBob,
);
// Bob reads the file Alice wrote
final tmpDir = Directory.systemTemp;
final outFile = File('${tmpDir.path}/received.txt');
await vaultBob.read('shared/message.txt', outFile.path);
// Bob reads and displays the content
final content = await outFile.readAsString();
print('Bob received: $content');
}
import ink.francesco.bao.*;
import java.nio.file.Files;
import java.nio.file.Path;
public class QuickStart {
public static void main(String[] args) throws Exception {
// Use the same store configuration as Alice
var storeConfig = StoreConfig.s3(
"my-vault",
"s3.amazonaws.com",
"us-east-1",
"my-bucket",
"bao",
"your-key-id",
"your-secret"
);
var store = Store.open(storeConfig);
// Create a database for Bob's vault
var dbBob = new DB("bob_vault.db");
// Bob opens Alice's vault using Alice's public ID
// (bob and bobSecret are from Step 1, alice is Alice's public ID from Step 1)
var vaultBob = Vault.open(
bobSecret,
alice,
store,
dbBob
);
// Bob reads the file Alice wrote
Path outFile = Files.createTempFile("received", ".txt");
vaultBob.read("shared/message.txt", outFile.toString());
// Bob reads and displays the content
String content = Files.readString(outFile);
System.out.println("Bob received: " + content);
}
}
Learn More
This quick start shows the basics of creating identities, vaults, and sharing files between two users. For comprehensive documentation including:
- Installation details for each platform
- Advanced vault configuration and access control patterns
- File versioning and metadata
- Database replication with Replica
- Encrypted messaging with Mailbox
- And much more…
See the complete guide.