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_config = {
'type': 's3',
'id': 'my-vault',
's3': {
'bucket': 'my-bucket',
'endpoint': 's3.amazonaws.com',
'prefix': 'bao',
'auth': {
'accessKeyId': 'your-key-id',
'secretAccessKey': 'your-secret'
}
}
}
store = Store(store_config)
# 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(Vault.users, alice_secret, store, db_alice)
# Alice grants Bob access to her vault
vault_alice.sync_access(0, 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/vault"
)
func main() {
// Configure cloud storage
store, err := lib.OpenStore(lib.StoreConfig{
Type: "s3",
Id: "my-vault",
S3: lib.S3Config{
Bucket: "my-bucket",
Endpoint: "s3.amazonaws.com",
Prefix: "bao",
Auth: lib.S3Auth{
AccessKeyId: "your-key-id",
SecretAccessKey: "your-secret",
},
},
})
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(vault.Users, aliceSecret, store, dbAlice, vault.Config{})
if err != nil {
panic(err)
}
// Alice grants Bob access to her vault
err = vaultAlice.SyncAccess(0, 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, 0, nil)
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 = DB('alice_vault.db');
// Alice creates a vault (she already has alice and aliceSecret from Step 1)
final vaultAlice = await Vault.create(
Vault.users,
aliceSecret,
store,
dbAlice,
);
// Alice grants Bob access to her vault
await vaultAlice.syncAccess(0, [
AccessChange(userId: bob, access: AccessLevel.readWrite),
]);
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;
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(
Vault.USERS,
aliceSecret,
store,
dbAlice
);
// Alice grants Bob access to her vault
vaultAlice.syncAccess(0, new AccessChange[]{
new AccessChange(bob, AccessLevel.READ_WRITE)
});
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", 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_config = {
'type': 's3',
'id': 'my-vault',
's3': {
'bucket': 'my-bucket',
'endpoint': 's3.amazonaws.com',
'prefix': 'bao',
'auth': {
'accessKeyId': 'your-key-id',
'secretAccessKey': 'your-secret'
}
}
}
store = Store(store_config)
# 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(Vault.users, 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/vault"
)
func main() {
// Use the same store configuration as Alice
store, err := lib.OpenStore(lib.StoreConfig{
Type: "s3",
Id: "my-vault",
S3: lib.S3Config{
Bucket: "my-bucket",
Endpoint: "s3.amazonaws.com",
Prefix: "bao",
Auth: lib.S3Auth{
AccessKeyId: "your-key-id",
SecretAccessKey: "your-secret",
},
},
})
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(vault.Users, 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, 0, 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 = 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)
final vaultBob = await Vault.open(
Vault.users,
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(
Vault.USERS,
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 configurations (Home and All realms)
- File versioning and metadata
- Database replication with Replica
- Encrypted messaging with Mailbox
- And much more…
See the complete guide.