Harkonnen Vault
Object storage S3-compatible
Almacenamiento de objetos compatible con la API S3 estándar. Consenso Raft integrado en un único binario — sin etcd, sin ZooKeeper, sin dependencias externas. WORM (Write Once Read Many) para cumplimiento HIPAA. Recibe los Parquet de Harvester y los sirve a Sietch para consultas analíticas.
Características
- ✦API 100% compatible con AWS S3
- ✦Consenso Raft integrado — sin etcd ni ZooKeeper
- ✦WORM (Write Once Read Many) para compliance HIPAA
- ✦Binario único — sin dependencias externas
- ✦Replicación automática entre nodos del cluster
- ✦Encriptación at-rest con AES-256
- ✦Recibe Parquet de Harvester, sirve a Sietch
- ✦Datos locales — soberanía total, nunca salen del cluster
- ✦Compatible con AWS CLI, boto3 y cualquier SDK S3
Configuración
toml
# /etc/dune/vault.toml
[server]
bind = "0.0.0.0:7460"
[storage]
data_dir = "/var/lib/dune/vault"
max_disk = "500GB"
[raft]
peers = ["10.10.0.10:7461", "10.10.0.11:7461", "10.10.0.12:7461"]
[replication]
factor = 2 # copias por objeto
[worm]
enabled = true # Write Once Read Many
retention = "7y" # retención mínima HIPAA
[encryption]
at_rest = true
algorithm = "AES-256-GCM"CLI
bash
# Listar buckets
dune vault buckets list
# BUCKET OBJECTS SIZE WORM CREATED
# data-lake 12,847 142 GB yes 2026-01-15
# backups 89 28 GB no 2026-01-15
# audit-logs 3,291 4.2 GB yes 2026-02-01
# Subir Parquet (desde Harvester)
dune vault put data-lake/exports/2026-03-23.parquet ./export.parquet
# ✦ Uploaded: 4.7MB in 0.1s
# ✦ Replicated to 2 nodes (Raft)
# ✦ WORM lock: immutable
# Compatible con AWS CLI
aws --endpoint-url http://localhost:7460 s3 ls s3://data-lake/exports/
# 2026-03-23 14:30 4.7MB 2026-03-23.parquet
# 2026-03-22 14:30 4.8MB 2026-03-22.parquet
# Crear bucket con WORM
dune vault buckets create --name compliance --worm --retention 7yUso con SDKs de S3
python
import boto3
s3 = boto3.client(
"s3",
endpoint_url="http://localhost:7460",
aws_access_key_id="dune-access-key",
aws_secret_access_key="dune-secret-key",
)
# Subir archivo
s3.upload_file("scan.dcm", "medical-images", "patient-001/ct-scan.dcm")
# Listar objetos
response = s3.list_objects_v2(Bucket="medical-images", Prefix="patient-001/")
for obj in response["Contents"]:
print(f"{obj['Key']} — {obj['Size']} bytes")