RustLicenseLicenseCICodecovdependency status


Aruna logo


A FAIR, federated data orchestration engine

Warning

Work in progress! You are viewing the upcoming version 3. See the v2 branch for the latest stable release.

Aruna is a federated peer-to-peer data orchestration engine that enables organizations to share and organize data and metadata without handing over control to a central platform.

Features

  • Sovereign trust model: Each node belongs to one organization. Realms define shared trust between them.
  • Fine-grained access control: Path-based permissions with wildcard support and group-based roles.
  • S3-compatible API: Every node exposes an S3 API for data access.
  • Virtual buckets: Buckets are virtual collections of local and remote data resources, with configurable materialization behavior.
  • Extensible storage backends: Support for a variety of storage backends through OpenDAL.
  • Standardized metadata: Metadata is stored as RO-Crate JSON-LD enabling rich, interoperable descriptions of datasets, files, and processes.
  • Powerful metadata manipulation: RO-Crates can be created, edited and viewed through SPARQL queries and updates.
  • Distributed full-text search: Per-node Tantivy indexes with fan-out queries and authorization filtering.
  • Built-in replication and synchronization: Metadata and data are replicated across nodes with automatic conflict resolution.
  • Interoperable using open standards: OIDC for authentication, GA4GH DRS for data referencing, OAI-PMH for metadata harvesting.
  • AI assistant tools: Authenticated MCP access to Aruna context, data, metadata, and compute operations.
  • Easy deployment: Run a node as a single binary or deploy a multi-node cluster.

Architecture and Goals

Aruna is built for research data that does not live in one place, and often cannot be moved into one. Universities, institutes, labs, archives, repositories and infrastructure providers each have their own storage systems, policies, identities, and responsibilities. A central platform can be convenient, but it also creates a new point of control and tends to clash with legal, organizational, or practical constraints. Aruna takes a different approach: every participating organization runs its own node, keeps authority over its data, and still joins a shared network for discovery, access, replication, and collaboration.

The system is organized around realms. A realm is an organizational trust boundary, such as an institute, department, consortium, or project network. Each node belongs to one realm, and realms can establish trust with each other when collaboration requires it. Trust is not the same as access. A trusted partner does not automatically gain permission to read or modify data. Access stays explicit, granted through groups, roles, and path-based permissions. Data sits with the organization responsible for it, while researchers can still work across institutions.

Data, metadata, and access

Each Aruna node exposes an S3-compatible API, so researchers can keep using the tools, scripts, workflow systems, and libraries they already have instead of learning a new storage protocol. Buckets are virtual collections that mix local data, replicated data, and references to remote resources. To a user, this looks like one coherent access point. Underneath, Aruna tracks where data actually lives, which permissions apply, and whether an object should be materialized locally or fetched on demand.

Note

Object keys for PutObject, CreateMultipartUpload, UploadPart, and CompleteMultipartUpload must be non-empty relative paths; they are rejected if they begin with /, contain an exact .. path segment, or contain control characters.

Metadata is part of the core system, not an external catalog bolted on afterwards. Descriptions are stored as RO-Crate JSON-LD, so datasets, files, people, instruments, workflows, software, and process runs can be described in a shared format. These descriptions live in a CRDT-based triple store, which allows concurrent edits on different nodes and merges them without a single authority arbitrating the result. Management resources such as users and groups are synchronized through durable document-sync topics, which lets nodes keep working through network outages and reconcile state once they reconnect.

File contents go into a content-addressed blob layer. Objects are hashed with BLAKE3, making integrity checks and deduplication part of the storage model rather than a separate step. If the same file shows up under different paths or on different nodes, it is recognized by its content instead of its location. Replication uses Bao-tree verified streaming, so data can be checked incrementally as it arrives.

Network and research workflows

The network layer is built on iroh, which gives Aruna a peer-to-peer foundation for node discovery, authenticated communication, and direct exchange between nodes, even if they are behind NATs or firewalls.

For researchers, the data remains where it is, but becomes easier to find, describe, access, replicate and incorporate into workflows. Familiar S3 tooling keeps working, while Aruna adds shared metadata, authorization, replication, provenance, and standards-based interoperability on top of the existing infrastructure.

Aruna serves as a base layer for larger research infrastructures. Distributed full-text search, GA4GH DRS identifiers, OAI-PMH harvesting, GA4GH TES-based compute execution, CEL-based policy enforcement, event subscriptions, and transparent request forwarding all rest on the same foundation: sovereign nodes, shared metadata, verified data exchange, and open interfaces.

The goal is to support FAIR data practice in a way that matches how research actually works: distributed, collaborative, policy-bound, and owned by many parties at once.

Getting Started

The quickest way to try Aruna is a local 3-node demo deployment.

Prerequisites

For local builds:

For local test deployments:

  • curl (ss for cluster setup)
  • docker
  • docker-compose
  • just (optional, for convenience)

Run a single node with an external identity provider

Start one node with:

just local

or invoke scripts/local_deploy.sh directly.

The default example configuration exposes:

  • the REST API and Swagger UI on http://127.0.0.1:3000/swagger-ui
  • the S3 endpoint on http://127.0.0.1:1337

Evaluate a local cluster

For a quick end-to-end evaluation, run:

just local-cluster
# or
just local-cluster-oidc

This demo deployment:

  • builds the workspace in release mode
  • launches 3 local Aruna nodes
  • waits for readiness at http://127.0.0.1:<port>/swagger-ui
  • writes per-node logs, summary.txt and a private credentials.txt to target/test-deploy/
  • prints an ADMIN_TOKEN=... line for use in authenticated API calls during the session
  • prints a summary listing every node's API, portal, S3 and ops URLs next to the test logins

just preview additionally serves the portal. The portal has its own listener, so each node exposes the SPA on a separate port from the REST API; the REST port redirects / to the Swagger UI.

Useful overrides:

  • ARUNA_TEST_DEPLOY_BASE_PORT shifts the entire local port range
  • ARUNA_TEST_DEPLOY_EXIT_AFTER_READY=1 exits once the cluster is ready instead of keeping it running

Ctrl-C stops the cluster again. A deployment that outlived its terminal is stopped with:

just stop

It interrupts a deploy script that still monitors the nodes, stops every node named by a pid file under target/test-deploy/, and removes the Keycloak compose project. Logs, summary.txt and credentials.txt stay in place.

just local-cluster-oidc extends the same 3-node startup check with a local Keycloak instance.

Run a single node from source

To run a node directly from source, copy the example environment file and start the main binary from the workspace root:

cp .env.example .env
cargo run -p aruna

The default example configuration exposes:

  • the REST API and Swagger UI on http://127.0.0.1:3000/swagger-ui
  • the S3 endpoint on http://127.0.0.1:1337

State And Onboarding

A node started without an ONBOARDING_SECRET initializes a new realm on first boot and persists its identity under STORAGE_PATH. When this happens, the first management node also logs an initial local onboarding secret for the new realm.

Additional nodes join an existing realm by setting ONBOARDING_SECRET on their first boot.

Onboarding only takes effect on a fresh data directory. Once a node has persisted state, later .env changes, including a new ONBOARDING_SECRET, do not re-bootstrap or re-onboard it. To repeat an onboarding or bootstrap flow, point the node at a fresh STORAGE_PATH.

For a ready-made multi-node onboarding flow, use just local-cluster instead of walking through the onboarding APIs manually.

Durability Configuration

ARUNA_FJALL_PERSIST_MODE controls the Fjall persist mode used by Aruna's local storage engine and document-sync metadata state.

ValueDurability contract
buffer (default)Flushes data to OS buffers before local Fjall persistence returns. This keeps write latency low and protects against an application crash, but recently acknowledged writes are not guaranteed after an OS crash or power loss.
sync_allFlushes data and metadata with fsync before local Fjall persistence returns. This gives stronger local crash durability at higher write latency.

The setting does not change replication, authorization, or RO-Crate semantics. Metadata requests marked MetadataRequestDurability::WalAlreadyDurable have already been accepted by the metadata event-log phase, so document-sync projection flushes may be deferred. The event-log write and later projection flush still use the configured Fjall mode; buffer does not become fsync-durable because a request is WAL-first.

Object-backed RO-Crate imports copy the archive into a hidden seekable spool. Until that spool is deleted at the end of the import, the importing node can temporarily use roughly twice the archive's stored bytes; operators should reserve capacity accordingly.

License

Aruna is licensed under either of

at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Aruna by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Feedback & Contributions

If you have any ideas, suggestions, or issues, please don't hesitate to open an issue and/or PR. Contributions to this project are always welcome! We appreciate your help in making this project better. Please have a look at our Contributor Guidelines as well as our Code of Conduct for more information.

About

The data orchestration engine

Resources

Code of conduct

Contributing

Stars

23 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

RustLicenseLicenseCICodecovdependency status


Aruna logo


A FAIR, federated data orchestration engine

Warning

Work in progress! You are viewing the upcoming version 3. See the v2 branch for the latest stable release.

Aruna is a federated peer-to-peer data orchestration engine that enables organizations to share and organize data and metadata without handing over control to a central platform.

Features

  • Sovereign trust model: Each node belongs to one organization. Realms define shared trust between them.
  • Fine-grained access control: Path-based permissions with wildcard support and group-based roles.
  • S3-compatible API: Every node exposes an S3 API for data access.
  • Virtual buckets: Buckets are virtual collections of local and remote data resources, with configurable materialization behavior.
  • Extensible storage backends: Support for a variety of storage backends through OpenDAL.
  • Standardized metadata: Metadata is stored as RO-Crate JSON-LD enabling rich, interoperable descriptions of datasets, files, and processes.
  • Powerful metadata manipulation: RO-Crates can be created, edited and viewed through SPARQL queries and updates.
  • Distributed full-text search: Per-node Tantivy indexes with fan-out queries and authorization filtering.
  • Built-in replication and synchronization: Metadata and data are replicated across nodes with automatic conflict resolution.
  • Interoperable using open standards: OIDC for authentication, GA4GH DRS for data referencing, OAI-PMH for metadata harvesting.
  • AI assistant tools: Authenticated MCP access to Aruna context, data, metadata, and compute operations.
  • Easy deployment: Run a node as a single binary or deploy a multi-node cluster.

Architecture and Goals

Aruna is built for research data that does not live in one place, and often cannot be moved into one. Universities, institutes, labs, archives, repositories and infrastructure providers each have their own storage systems, policies, identities, and responsibilities. A central platform can be convenient, but it also creates a new point of control and tends to clash with legal, organizational, or practical constraints. Aruna takes a different approach: every participating organization runs its own node, keeps authority over its data, and still joins a shared network for discovery, access, replication, and collaboration.

The system is organized around realms. A realm is an organizational trust boundary, such as an institute, department, consortium, or project network. Each node belongs to one realm, and realms can establish trust with each other when collaboration requires it. Trust is not the same as access. A trusted partner does not automatically gain permission to read or modify data. Access stays explicit, granted through groups, roles, and path-based permissions. Data sits with the organization responsible for it, while researchers can still work across institutions.

Data, metadata, and access

Each Aruna node exposes an S3-compatible API, so researchers can keep using the tools, scripts, workflow systems, and libraries they already have instead of learning a new storage protocol. Buckets are virtual collections that mix local data, replicated data, and references to remote resources. To a user, this looks like one coherent access point. Underneath, Aruna tracks where data actually lives, which permissions apply, and whether an object should be materialized locally or fetched on demand.

Note

Object keys for PutObject, CreateMultipartUpload, UploadPart, and CompleteMultipartUpload must be non-empty relative paths; they are rejected if they begin with /, contain an exact .. path segment, or contain control characters.

Metadata is part of the core system, not an external catalog bolted on afterwards. Descriptions are stored as RO-Crate JSON-LD, so datasets, files, people, instruments, workflows, software, and process runs can be described in a shared format. These descriptions live in a CRDT-based triple store, which allows concurrent edits on different nodes and merges them without a single authority arbitrating the result. Management resources such as users and groups are synchronized through durable document-sync topics, which lets nodes keep working through network outages and reconcile state once they reconnect.

File contents go into a content-addressed blob layer. Objects are hashed with BLAKE3, making integrity checks and deduplication part of the storage model rather than a separate step. If the same file shows up under different paths or on different nodes, it is recognized by its content instead of its location. Replication uses Bao-tree verified streaming, so data can be checked incrementally as it arrives.

Network and research workflows

The network layer is built on iroh, which gives Aruna a peer-to-peer foundation for node discovery, authenticated communication, and direct exchange between nodes, even if they are behind NATs or firewalls.

For researchers, the data remains where it is, but becomes easier to find, describe, access, replicate and incorporate into workflows. Familiar S3 tooling keeps working, while Aruna adds shared metadata, authorization, replication, provenance, and standards-based interoperability on top of the existing infrastructure.

Aruna serves as a base layer for larger research infrastructures. Distributed full-text search, GA4GH DRS identifiers, OAI-PMH harvesting, GA4GH TES-based compute execution, CEL-based policy enforcement, event subscriptions, and transparent request forwarding all rest on the same foundation: sovereign nodes, shared metadata, verified data exchange, and open interfaces.

The goal is to support FAIR data practice in a way that matches how research actually works: distributed, collaborative, policy-bound, and owned by many parties at once.

Getting Started

The quickest way to try Aruna is a local 3-node demo deployment.

Prerequisites

For local builds:

For local test deployments:

  • curl (ss for cluster setup)
  • docker
  • docker-compose
  • just (optional, for convenience)

Run a single node with an external identity provider

Start one node with:

just local

or invoke scripts/local_deploy.sh directly.

The default example configuration exposes:

  • the REST API and Swagger UI on http://127.0.0.1:3000/swagger-ui
  • the S3 endpoint on http://127.0.0.1:1337

Evaluate a local cluster

For a quick end-to-end evaluation, run:

just local-cluster
# or
just local-cluster-oidc

This demo deployment:

  • builds the workspace in release mode
  • launches 3 local Aruna nodes
  • waits for readiness at http://127.0.0.1:<port>/swagger-ui
  • writes per-node logs, summary.txt and a private credentials.txt to target/test-deploy/
  • prints an ADMIN_TOKEN=... line for use in authenticated API calls during the session
  • prints a summary listing every node's API, portal, S3 and ops URLs next to the test logins

just preview additionally serves the portal. The portal has its own listener, so each node exposes the SPA on a separate port from the REST API; the REST port redirects / to the Swagger UI.

Useful overrides:

  • ARUNA_TEST_DEPLOY_BASE_PORT shifts the entire local port range
  • ARUNA_TEST_DEPLOY_EXIT_AFTER_READY=1 exits once the cluster is ready instead of keeping it running

Ctrl-C stops the cluster again. A deployment that outlived its terminal is stopped with:

just stop

It interrupts a deploy script that still monitors the nodes, stops every node named by a pid file under target/test-deploy/, and removes the Keycloak compose project. Logs, summary.txt and credentials.txt stay in place.

just local-cluster-oidc extends the same 3-node startup check with a local Keycloak instance.

Run a single node from source

To run a node directly from source, copy the example environment file and start the main binary from the workspace root:

cp .env.example .env
cargo run -p aruna

The default example configuration exposes:

  • the REST API and Swagger UI on http://127.0.0.1:3000/swagger-ui
  • the S3 endpoint on http://127.0.0.1:1337

State And Onboarding

A node started without an ONBOARDING_SECRET initializes a new realm on first boot and persists its identity under STORAGE_PATH. When this happens, the first management node also logs an initial local onboarding secret for the new realm.

Additional nodes join an existing realm by setting ONBOARDING_SECRET on their first boot.

Onboarding only takes effect on a fresh data directory. Once a node has persisted state, later .env changes, including a new ONBOARDING_SECRET, do not re-bootstrap or re-onboard it. To repeat an onboarding or bootstrap flow, point the node at a fresh STORAGE_PATH.

For a ready-made multi-node onboarding flow, use just local-cluster instead of walking through the onboarding APIs manually.

Durability Configuration

ARUNA_FJALL_PERSIST_MODE controls the Fjall persist mode used by Aruna's local storage engine and document-sync metadata state.

ValueDurability contract
buffer (default)Flushes data to OS buffers before local Fjall persistence returns. This keeps write latency low and protects against an application crash, but recently acknowledged writes are not guaranteed after an OS crash or power loss.
sync_allFlushes data and metadata with fsync before local Fjall persistence returns. This gives stronger local crash durability at higher write latency.

The setting does not change replication, authorization, or RO-Crate semantics. Metadata requests marked MetadataRequestDurability::WalAlreadyDurable have already been accepted by the metadata event-log phase, so document-sync projection flushes may be deferred. The event-log write and later projection flush still use the configured Fjall mode; buffer does not become fsync-durable because a request is WAL-first.

Object-backed RO-Crate imports copy the archive into a hidden seekable spool. Until that spool is deleted at the end of the import, the importing node can temporarily use roughly twice the archive's stored bytes; operators should reserve capacity accordingly.

License

Aruna is licensed under either of

at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Aruna by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Feedback & Contributions

If you have any ideas, suggestions, or issues, please don't hesitate to open an issue and/or PR. Contributions to this project are always welcome! We appreciate your help in making this project better. Please have a look at our Contributor Guidelines as well as our Code of Conduct for more information.

About

The data orchestration engine

Resources

Code of conduct

Contributing

Stars

23 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

RustLicenseLicenseCICodecovdependency status


Aruna logo


A FAIR, federated data orchestration engine

Warning

Work in progress! You are viewing the upcoming version 3. See the v2 branch for the latest stable release.

Aruna is a federated peer-to-peer data orchestration engine that enables organizations to share and organize data and metadata without handing over control to a central platform.

Features

  • Sovereign trust model: Each node belongs to one organization. Realms define shared trust between them.
  • Fine-grained access control: Path-based permissions with wildcard support and group-based roles.
  • S3-compatible API: Every node exposes an S3 API for data access.
  • Virtual buckets: Buckets are virtual collections of local and remote data resources, with configurable materialization behavior.
  • Extensible storage backends: Support for a variety of storage backends through OpenDAL.
  • Standardized metadata: Metadata is stored as RO-Crate JSON-LD enabling rich, interoperable descriptions of datasets, files, and processes.
  • Powerful metadata manipulation: RO-Crates can be created, edited and viewed through SPARQL queries and updates.
  • Distributed full-text search: Per-node Tantivy indexes with fan-out queries and authorization filtering.
  • Built-in replication and synchronization: Metadata and data are replicated across nodes with automatic conflict resolution.
  • Interoperable using open standards: OIDC for authentication, GA4GH DRS for data referencing, OAI-PMH for metadata harvesting.
  • AI assistant tools: Authenticated MCP access to Aruna context, data, metadata, and compute operations.
  • Easy deployment: Run a node as a single binary or deploy a multi-node cluster.

Architecture and Goals

Aruna is built for research data that does not live in one place, and often cannot be moved into one. Universities, institutes, labs, archives, repositories and infrastructure providers each have their own storage systems, policies, identities, and responsibilities. A central platform can be convenient, but it also creates a new point of control and tends to clash with legal, organizational, or practical constraints. Aruna takes a different approach: every participating organization runs its own node, keeps authority over its data, and still joins a shared network for discovery, access, replication, and collaboration.

The system is organized around realms. A realm is an organizational trust boundary, such as an institute, department, consortium, or project network. Each node belongs to one realm, and realms can establish trust with each other when collaboration requires it. Trust is not the same as access. A trusted partner does not automatically gain permission to read or modify data. Access stays explicit, granted through groups, roles, and path-based permissions. Data sits with the organization responsible for it, while researchers can still work across institutions.

Data, metadata, and access

Each Aruna node exposes an S3-compatible API, so researchers can keep using the tools, scripts, workflow systems, and libraries they already have instead of learning a new storage protocol. Buckets are virtual collections that mix local data, replicated data, and references to remote resources. To a user, this looks like one coherent access point. Underneath, Aruna tracks where data actually lives, which permissions apply, and whether an object should be materialized locally or fetched on demand.

Note

Object keys for PutObject, CreateMultipartUpload, UploadPart, and CompleteMultipartUpload must be non-empty relative paths; they are rejected if they begin with /, contain an exact .. path segment, or contain control characters.

Metadata is part of the core system, not an external catalog bolted on afterwards. Descriptions are stored as RO-Crate JSON-LD, so datasets, files, people, instruments, workflows, software, and process runs can be described in a shared format. These descriptions live in a CRDT-based triple store, which allows concurrent edits on different nodes and merges them without a single authority arbitrating the result. Management resources such as users and groups are synchronized through durable document-sync topics, which lets nodes keep working through network outages and reconcile state once they reconnect.

File contents go into a content-addressed blob layer. Objects are hashed with BLAKE3, making integrity checks and deduplication part of the storage model rather than a separate step. If the same file shows up under different paths or on different nodes, it is recognized by its content instead of its location. Replication uses Bao-tree verified streaming, so data can be checked incrementally as it arrives.

Network and research workflows

The network layer is built on iroh, which gives Aruna a peer-to-peer foundation for node discovery, authenticated communication, and direct exchange between nodes, even if they are behind NATs or firewalls.

For researchers, the data remains where it is, but becomes easier to find, describe, access, replicate and incorporate into workflows. Familiar S3 tooling keeps working, while Aruna adds shared metadata, authorization, replication, provenance, and standards-based interoperability on top of the existing infrastructure.

Aruna serves as a base layer for larger research infrastructures. Distributed full-text search, GA4GH DRS identifiers, OAI-PMH harvesting, GA4GH TES-based compute execution, CEL-based policy enforcement, event subscriptions, and transparent request forwarding all rest on the same foundation: sovereign nodes, shared metadata, verified data exchange, and open interfaces.

The goal is to support FAIR data practice in a way that matches how research actually works: distributed, collaborative, policy-bound, and owned by many parties at once.

Getting Started

The quickest way to try Aruna is a local 3-node demo deployment.

Prerequisites

For local builds:

For local test deployments:

  • curl (ss for cluster setup)
  • docker
  • docker-compose
  • just (optional, for convenience)

Run a single node with an external identity provider

Start one node with:

just local

or invoke scripts/local_deploy.sh directly.

The default example configuration exposes:

  • the REST API and Swagger UI on http://127.0.0.1:3000/swagger-ui
  • the S3 endpoint on http://127.0.0.1:1337

Evaluate a local cluster

For a quick end-to-end evaluation, run:

just local-cluster
# or
just local-cluster-oidc

This demo deployment:

  • builds the workspace in release mode
  • launches 3 local Aruna nodes
  • waits for readiness at http://127.0.0.1:<port>/swagger-ui
  • writes per-node logs, summary.txt and a private credentials.txt to target/test-deploy/
  • prints an ADMIN_TOKEN=... line for use in authenticated API calls during the session
  • prints a summary listing every node's API, portal, S3 and ops URLs next to the test logins

just preview additionally serves the portal. The portal has its own listener, so each node exposes the SPA on a separate port from the REST API; the REST port redirects / to the Swagger UI.

Useful overrides:

  • ARUNA_TEST_DEPLOY_BASE_PORT shifts the entire local port range
  • ARUNA_TEST_DEPLOY_EXIT_AFTER_READY=1 exits once the cluster is ready instead of keeping it running

Ctrl-C stops the cluster again. A deployment that outlived its terminal is stopped with:

just stop

It interrupts a deploy script that still monitors the nodes, stops every node named by a pid file under target/test-deploy/, and removes the Keycloak compose project. Logs, summary.txt and credentials.txt stay in place.

just local-cluster-oidc extends the same 3-node startup check with a local Keycloak instance.

Run a single node from source

To run a node directly from source, copy the example environment file and start the main binary from the workspace root:

cp .env.example .env
cargo run -p aruna

The default example configuration exposes:

  • the REST API and Swagger UI on http://127.0.0.1:3000/swagger-ui
  • the S3 endpoint on http://127.0.0.1:1337

State And Onboarding

A node started without an ONBOARDING_SECRET initializes a new realm on first boot and persists its identity under STORAGE_PATH. When this happens, the first management node also logs an initial local onboarding secret for the new realm.

Additional nodes join an existing realm by setting ONBOARDING_SECRET on their first boot.

Onboarding only takes effect on a fresh data directory. Once a node has persisted state, later .env changes, including a new ONBOARDING_SECRET, do not re-bootstrap or re-onboard it. To repeat an onboarding or bootstrap flow, point the node at a fresh STORAGE_PATH.

For a ready-made multi-node onboarding flow, use just local-cluster instead of walking through the onboarding APIs manually.

Durability Configuration

ARUNA_FJALL_PERSIST_MODE controls the Fjall persist mode used by Aruna's local storage engine and document-sync metadata state.

ValueDurability contract
buffer (default)Flushes data to OS buffers before local Fjall persistence returns. This keeps write latency low and protects against an application crash, but recently acknowledged writes are not guaranteed after an OS crash or power loss.
sync_allFlushes data and metadata with fsync before local Fjall persistence returns. This gives stronger local crash durability at higher write latency.

The setting does not change replication, authorization, or RO-Crate semantics. Metadata requests marked MetadataRequestDurability::WalAlreadyDurable have already been accepted by the metadata event-log phase, so document-sync projection flushes may be deferred. The event-log write and later projection flush still use the configured Fjall mode; buffer does not become fsync-durable because a request is WAL-first.

Object-backed RO-Crate imports copy the archive into a hidden seekable spool. Until that spool is deleted at the end of the import, the importing node can temporarily use roughly twice the archive's stored bytes; operators should reserve capacity accordingly.

License

Aruna is licensed under either of

at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Aruna by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Feedback & Contributions

If you have any ideas, suggestions, or issues, please don't hesitate to open an issue and/or PR. Contributions to this project are always welcome! We appreciate your help in making this project better. Please have a look at our Contributor Guidelines as well as our Code of Conduct for more information.

About

The data orchestration engine

Resources

Code of conduct

Contributing

Stars

23 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

RustLicenseLicenseCICodecovdependency status


Aruna logo


A FAIR, federated data orchestration engine

Warning

Work in progress! You are viewing the upcoming version 3. See the v2 branch for the latest stable release.

Aruna is a federated peer-to-peer data orchestration engine that enables organizations to share and organize data and metadata without handing over control to a central platform.

Features

  • Sovereign trust model: Each node belongs to one organization. Realms define shared trust between them.
  • Fine-grained access control: Path-based permissions with wildcard support and group-based roles.
  • S3-compatible API: Every node exposes an S3 API for data access.
  • Virtual buckets: Buckets are virtual collections of local and remote data resources, with configurable materialization behavior.
  • Extensible storage backends: Support for a variety of storage backends through OpenDAL.
  • Standardized metadata: Metadata is stored as RO-Crate JSON-LD enabling rich, interoperable descriptions of datasets, files, and processes.
  • Powerful metadata manipulation: RO-Crates can be created, edited and viewed through SPARQL queries and updates.
  • Distributed full-text search: Per-node Tantivy indexes with fan-out queries and authorization filtering.
  • Built-in replication and synchronization: Metadata and data are replicated across nodes with automatic conflict resolution.
  • Interoperable using open standards: OIDC for authentication, GA4GH DRS for data referencing, OAI-PMH for metadata harvesting.
  • AI assistant tools: Authenticated MCP access to Aruna context, data, metadata, and compute operations.
  • Easy deployment: Run a node as a single binary or deploy a multi-node cluster.

Architecture and Goals

Aruna is built for research data that does not live in one place, and often cannot be moved into one. Universities, institutes, labs, archives, repositories and infrastructure providers each have their own storage systems, policies, identities, and responsibilities. A central platform can be convenient, but it also creates a new point of control and tends to clash with legal, organizational, or practical constraints. Aruna takes a different approach: every participating organization runs its own node, keeps authority over its data, and still joins a shared network for discovery, access, replication, and collaboration.

The system is organized around realms. A realm is an organizational trust boundary, such as an institute, department, consortium, or project network. Each node belongs to one realm, and realms can establish trust with each other when collaboration requires it. Trust is not the same as access. A trusted partner does not automatically gain permission to read or modify data. Access stays explicit, granted through groups, roles, and path-based permissions. Data sits with the organization responsible for it, while researchers can still work across institutions.

Data, metadata, and access

Each Aruna node exposes an S3-compatible API, so researchers can keep using the tools, scripts, workflow systems, and libraries they already have instead of learning a new storage protocol. Buckets are virtual collections that mix local data, replicated data, and references to remote resources. To a user, this looks like one coherent access point. Underneath, Aruna tracks where data actually lives, which permissions apply, and whether an object should be materialized locally or fetched on demand.

Note

Object keys for PutObject, CreateMultipartUpload, UploadPart, and CompleteMultipartUpload must be non-empty relative paths; they are rejected if they begin with /, contain an exact .. path segment, or contain control characters.

Metadata is part of the core system, not an external catalog bolted on afterwards. Descriptions are stored as RO-Crate JSON-LD, so datasets, files, people, instruments, workflows, software, and process runs can be described in a shared format. These descriptions live in a CRDT-based triple store, which allows concurrent edits on different nodes and merges them without a single authority arbitrating the result. Management resources such as users and groups are synchronized through durable document-sync topics, which lets nodes keep working through network outages and reconcile state once they reconnect.

File contents go into a content-addressed blob layer. Objects are hashed with BLAKE3, making integrity checks and deduplication part of the storage model rather than a separate step. If the same file shows up under different paths or on different nodes, it is recognized by its content instead of its location. Replication uses Bao-tree verified streaming, so data can be checked incrementally as it arrives.

Network and research workflows

The network layer is built on iroh, which gives Aruna a peer-to-peer foundation for node discovery, authenticated communication, and direct exchange between nodes, even if they are behind NATs or firewalls.

For researchers, the data remains where it is, but becomes easier to find, describe, access, replicate and incorporate into workflows. Familiar S3 tooling keeps working, while Aruna adds shared metadata, authorization, replication, provenance, and standards-based interoperability on top of the existing infrastructure.

Aruna serves as a base layer for larger research infrastructures. Distributed full-text search, GA4GH DRS identifiers, OAI-PMH harvesting, GA4GH TES-based compute execution, CEL-based policy enforcement, event subscriptions, and transparent request forwarding all rest on the same foundation: sovereign nodes, shared metadata, verified data exchange, and open interfaces.

The goal is to support FAIR data practice in a way that matches how research actually works: distributed, collaborative, policy-bound, and owned by many parties at once.

Getting Started

The quickest way to try Aruna is a local 3-node demo deployment.

Prerequisites

For local builds:

For local test deployments:

  • curl (ss for cluster setup)
  • docker
  • docker-compose
  • just (optional, for convenience)

Run a single node with an external identity provider

Start one node with:

just local

or invoke scripts/local_deploy.sh directly.

The default example configuration exposes:

  • the REST API and Swagger UI on http://127.0.0.1:3000/swagger-ui
  • the S3 endpoint on http://127.0.0.1:1337

Evaluate a local cluster

For a quick end-to-end evaluation, run:

just local-cluster
# or
just local-cluster-oidc

This demo deployment:

  • builds the workspace in release mode
  • launches 3 local Aruna nodes
  • waits for readiness at http://127.0.0.1:<port>/swagger-ui
  • writes per-node logs, summary.txt and a private credentials.txt to target/test-deploy/
  • prints an ADMIN_TOKEN=... line for use in authenticated API calls during the session
  • prints a summary listing every node's API, portal, S3 and ops URLs next to the test logins

just preview additionally serves the portal. The portal has its own listener, so each node exposes the SPA on a separate port from the REST API; the REST port redirects / to the Swagger UI.

Useful overrides:

  • ARUNA_TEST_DEPLOY_BASE_PORT shifts the entire local port range
  • ARUNA_TEST_DEPLOY_EXIT_AFTER_READY=1 exits once the cluster is ready instead of keeping it running

Ctrl-C stops the cluster again. A deployment that outlived its terminal is stopped with:

just stop

It interrupts a deploy script that still monitors the nodes, stops every node named by a pid file under target/test-deploy/, and removes the Keycloak compose project. Logs, summary.txt and credentials.txt stay in place.

just local-cluster-oidc extends the same 3-node startup check with a local Keycloak instance.

Run a single node from source

To run a node directly from source, copy the example environment file and start the main binary from the workspace root:

cp .env.example .env
cargo run -p aruna

The default example configuration exposes:

  • the REST API and Swagger UI on http://127.0.0.1:3000/swagger-ui
  • the S3 endpoint on http://127.0.0.1:1337

State And Onboarding

A node started without an ONBOARDING_SECRET initializes a new realm on first boot and persists its identity under STORAGE_PATH. When this happens, the first management node also logs an initial local onboarding secret for the new realm.

Additional nodes join an existing realm by setting ONBOARDING_SECRET on their first boot.

Onboarding only takes effect on a fresh data directory. Once a node has persisted state, later .env changes, including a new ONBOARDING_SECRET, do not re-bootstrap or re-onboard it. To repeat an onboarding or bootstrap flow, point the node at a fresh STORAGE_PATH.

For a ready-made multi-node onboarding flow, use just local-cluster instead of walking through the onboarding APIs manually.

Durability Configuration

ARUNA_FJALL_PERSIST_MODE controls the Fjall persist mode used by Aruna's local storage engine and document-sync metadata state.

ValueDurability contract
buffer (default)Flushes data to OS buffers before local Fjall persistence returns. This keeps write latency low and protects against an application crash, but recently acknowledged writes are not guaranteed after an OS crash or power loss.
sync_allFlushes data and metadata with fsync before local Fjall persistence returns. This gives stronger local crash durability at higher write latency.

The setting does not change replication, authorization, or RO-Crate semantics. Metadata requests marked MetadataRequestDurability::WalAlreadyDurable have already been accepted by the metadata event-log phase, so document-sync projection flushes may be deferred. The event-log write and later projection flush still use the configured Fjall mode; buffer does not become fsync-durable because a request is WAL-first.

Object-backed RO-Crate imports copy the archive into a hidden seekable spool. Until that spool is deleted at the end of the import, the importing node can temporarily use roughly twice the archive's stored bytes; operators should reserve capacity accordingly.

License

Aruna is licensed under either of

at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Aruna by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Feedback & Contributions

If you have any ideas, suggestions, or issues, please don't hesitate to open an issue and/or PR. Contributions to this project are always welcome! We appreciate your help in making this project better. Please have a look at our Contributor Guidelines as well as our Code of Conduct for more information.

About

The data orchestration engine

Resources

Code of conduct

Contributing

Stars

23 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

RustLicenseLicenseCICodecovdependency status


Aruna logo


A FAIR, federated data orchestration engine

Warning

Work in progress! You are viewing the upcoming version 3. See the v2 branch for the latest stable release.

Aruna is a federated peer-to-peer data orchestration engine that enables organizations to share and organize data and metadata without handing over control to a central platform.

Features

  • Sovereign trust model: Each node belongs to one organization. Realms define shared trust between them.
  • Fine-grained access control: Path-based permissions with wildcard support and group-based roles.
  • S3-compatible API: Every node exposes an S3 API for data access.
  • Virtual buckets: Buckets are virtual collections of local and remote data resources, with configurable materialization behavior.
  • Extensible storage backends: Support for a variety of storage backends through OpenDAL.
  • Standardized metadata: Metadata is stored as RO-Crate JSON-LD enabling rich, interoperable descriptions of datasets, files, and processes.
  • Powerful metadata manipulation: RO-Crates can be created, edited and viewed through SPARQL queries and updates.
  • Distributed full-text search: Per-node Tantivy indexes with fan-out queries and authorization filtering.
  • Built-in replication and synchronization: Metadata and data are replicated across nodes with automatic conflict resolution.
  • Interoperable using open standards: OIDC for authentication, GA4GH DRS for data referencing, OAI-PMH for metadata harvesting.
  • AI assistant tools: Authenticated MCP access to Aruna context, data, metadata, and compute operations.
  • Easy deployment: Run a node as a single binary or deploy a multi-node cluster.

Architecture and Goals

Aruna is built for research data that does not live in one place, and often cannot be moved into one. Universities, institutes, labs, archives, repositories and infrastructure providers each have their own storage systems, policies, identities, and responsibilities. A central platform can be convenient, but it also creates a new point of control and tends to clash with legal, organizational, or practical constraints. Aruna takes a different approach: every participating organization runs its own node, keeps authority over its data, and still joins a shared network for discovery, access, replication, and collaboration.

The system is organized around realms. A realm is an organizational trust boundary, such as an institute, department, consortium, or project network. Each node belongs to one realm, and realms can establish trust with each other when collaboration requires it. Trust is not the same as access. A trusted partner does not automatically gain permission to read or modify data. Access stays explicit, granted through groups, roles, and path-based permissions. Data sits with the organization responsible for it, while researchers can still work across institutions.

Data, metadata, and access

Each Aruna node exposes an S3-compatible API, so researchers can keep using the tools, scripts, workflow systems, and libraries they already have instead of learning a new storage protocol. Buckets are virtual collections that mix local data, replicated data, and references to remote resources. To a user, this looks like one coherent access point. Underneath, Aruna tracks where data actually lives, which permissions apply, and whether an object should be materialized locally or fetched on demand.

Note

Object keys for PutObject, CreateMultipartUpload, UploadPart, and CompleteMultipartUpload must be non-empty relative paths; they are rejected if they begin with /, contain an exact .. path segment, or contain control characters.

Metadata is part of the core system, not an external catalog bolted on afterwards. Descriptions are stored as RO-Crate JSON-LD, so datasets, files, people, instruments, workflows, software, and process runs can be described in a shared format. These descriptions live in a CRDT-based triple store, which allows concurrent edits on different nodes and merges them without a single authority arbitrating the result. Management resources such as users and groups are synchronized through durable document-sync topics, which lets nodes keep working through network outages and reconcile state once they reconnect.

File contents go into a content-addressed blob layer. Objects are hashed with BLAKE3, making integrity checks and deduplication part of the storage model rather than a separate step. If the same file shows up under different paths or on different nodes, it is recognized by its content instead of its location. Replication uses Bao-tree verified streaming, so data can be checked incrementally as it arrives.

Network and research workflows

The network layer is built on iroh, which gives Aruna a peer-to-peer foundation for node discovery, authenticated communication, and direct exchange between nodes, even if they are behind NATs or firewalls.

For researchers, the data remains where it is, but becomes easier to find, describe, access, replicate and incorporate into workflows. Familiar S3 tooling keeps working, while Aruna adds shared metadata, authorization, replication, provenance, and standards-based interoperability on top of the existing infrastructure.

Aruna serves as a base layer for larger research infrastructures. Distributed full-text search, GA4GH DRS identifiers, OAI-PMH harvesting, GA4GH TES-based compute execution, CEL-based policy enforcement, event subscriptions, and transparent request forwarding all rest on the same foundation: sovereign nodes, shared metadata, verified data exchange, and open interfaces.

The goal is to support FAIR data practice in a way that matches how research actually works: distributed, collaborative, policy-bound, and owned by many parties at once.

Getting Started

The quickest way to try Aruna is a local 3-node demo deployment.

Prerequisites

For local builds:

For local test deployments:

  • curl (ss for cluster setup)
  • docker
  • docker-compose
  • just (optional, for convenience)

Run a single node with an external identity provider

Start one node with:

just local

or invoke scripts/local_deploy.sh directly.

The default example configuration exposes:

  • the REST API and Swagger UI on http://127.0.0.1:3000/swagger-ui
  • the S3 endpoint on http://127.0.0.1:1337

Evaluate a local cluster

For a quick end-to-end evaluation, run:

just local-cluster
# or
just local-cluster-oidc

This demo deployment:

  • builds the workspace in release mode
  • launches 3 local Aruna nodes
  • waits for readiness at http://127.0.0.1:<port>/swagger-ui
  • writes per-node logs, summary.txt and a private credentials.txt to target/test-deploy/
  • prints an ADMIN_TOKEN=... line for use in authenticated API calls during the session
  • prints a summary listing every node's API, portal, S3 and ops URLs next to the test logins

just preview additionally serves the portal. The portal has its own listener, so each node exposes the SPA on a separate port from the REST API; the REST port redirects / to the Swagger UI.

Useful overrides:

  • ARUNA_TEST_DEPLOY_BASE_PORT shifts the entire local port range
  • ARUNA_TEST_DEPLOY_EXIT_AFTER_READY=1 exits once the cluster is ready instead of keeping it running

Ctrl-C stops the cluster again. A deployment that outlived its terminal is stopped with:

just stop

It interrupts a deploy script that still monitors the nodes, stops every node named by a pid file under target/test-deploy/, and removes the Keycloak compose project. Logs, summary.txt and credentials.txt stay in place.

just local-cluster-oidc extends the same 3-node startup check with a local Keycloak instance.

Run a single node from source

To run a node directly from source, copy the example environment file and start the main binary from the workspace root:

cp .env.example .env
cargo run -p aruna

The default example configuration exposes:

  • the REST API and Swagger UI on http://127.0.0.1:3000/swagger-ui
  • the S3 endpoint on http://127.0.0.1:1337

State And Onboarding

A node started without an ONBOARDING_SECRET initializes a new realm on first boot and persists its identity under STORAGE_PATH. When this happens, the first management node also logs an initial local onboarding secret for the new realm.

Additional nodes join an existing realm by setting ONBOARDING_SECRET on their first boot.

Onboarding only takes effect on a fresh data directory. Once a node has persisted state, later .env changes, including a new ONBOARDING_SECRET, do not re-bootstrap or re-onboard it. To repeat an onboarding or bootstrap flow, point the node at a fresh STORAGE_PATH.

For a ready-made multi-node onboarding flow, use just local-cluster instead of walking through the onboarding APIs manually.

Durability Configuration

ARUNA_FJALL_PERSIST_MODE controls the Fjall persist mode used by Aruna's local storage engine and document-sync metadata state.

ValueDurability contract
buffer (default)Flushes data to OS buffers before local Fjall persistence returns. This keeps write latency low and protects against an application crash, but recently acknowledged writes are not guaranteed after an OS crash or power loss.
sync_allFlushes data and metadata with fsync before local Fjall persistence returns. This gives stronger local crash durability at higher write latency.

The setting does not change replication, authorization, or RO-Crate semantics. Metadata requests marked MetadataRequestDurability::WalAlreadyDurable have already been accepted by the metadata event-log phase, so document-sync projection flushes may be deferred. The event-log write and later projection flush still use the configured Fjall mode; buffer does not become fsync-durable because a request is WAL-first.

Object-backed RO-Crate imports copy the archive into a hidden seekable spool. Until that spool is deleted at the end of the import, the importing node can temporarily use roughly twice the archive's stored bytes; operators should reserve capacity accordingly.

License

Aruna is licensed under either of

at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Aruna by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Feedback & Contributions

If you have any ideas, suggestions, or issues, please don't hesitate to open an issue and/or PR. Contributions to this project are always welcome! We appreciate your help in making this project better. Please have a look at our Contributor Guidelines as well as our Code of Conduct for more information.

About

The data orchestration engine

Resources

Code of conduct

Contributing

Stars

23 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

RustLicenseLicenseCICodecovdependency status


Aruna logo


A FAIR, federated data orchestration engine

Warning

Work in progress! You are viewing the upcoming version 3. See the v2 branch for the latest stable release.

Aruna is a federated peer-to-peer data orchestration engine that enables organizations to share and organize data and metadata without handing over control to a central platform.

Features

  • Sovereign trust model: Each node belongs to one organization. Realms define shared trust between them.
  • Fine-grained access control: Path-based permissions with wildcard support and group-based roles.
  • S3-compatible API: Every node exposes an S3 API for data access.
  • Virtual buckets: Buckets are virtual collections of local and remote data resources, with configurable materialization behavior.
  • Extensible storage backends: Support for a variety of storage backends through OpenDAL.
  • Standardized metadata: Metadata is stored as RO-Crate JSON-LD enabling rich, interoperable descriptions of datasets, files, and processes.
  • Powerful metadata manipulation: RO-Crates can be created, edited and viewed through SPARQL queries and updates.
  • Distributed full-text search: Per-node Tantivy indexes with fan-out queries and authorization filtering.
  • Built-in replication and synchronization: Metadata and data are replicated across nodes with automatic conflict resolution.
  • Interoperable using open standards: OIDC for authentication, GA4GH DRS for data referencing, OAI-PMH for metadata harvesting.
  • AI assistant tools: Authenticated MCP access to Aruna context, data, metadata, and compute operations.
  • Easy deployment: Run a node as a single binary or deploy a multi-node cluster.

Architecture and Goals

Aruna is built for research data that does not live in one place, and often cannot be moved into one. Universities, institutes, labs, archives, repositories and infrastructure providers each have their own storage systems, policies, identities, and responsibilities. A central platform can be convenient, but it also creates a new point of control and tends to clash with legal, organizational, or practical constraints. Aruna takes a different approach: every participating organization runs its own node, keeps authority over its data, and still joins a shared network for discovery, access, replication, and collaboration.

The system is organized around realms. A realm is an organizational trust boundary, such as an institute, department, consortium, or project network. Each node belongs to one realm, and realms can establish trust with each other when collaboration requires it. Trust is not the same as access. A trusted partner does not automatically gain permission to read or modify data. Access stays explicit, granted through groups, roles, and path-based permissions. Data sits with the organization responsible for it, while researchers can still work across institutions.

Data, metadata, and access

Each Aruna node exposes an S3-compatible API, so researchers can keep using the tools, scripts, workflow systems, and libraries they already have instead of learning a new storage protocol. Buckets are virtual collections that mix local data, replicated data, and references to remote resources. To a user, this looks like one coherent access point. Underneath, Aruna tracks where data actually lives, which permissions apply, and whether an object should be materialized locally or fetched on demand.

Note

Object keys for PutObject, CreateMultipartUpload, UploadPart, and CompleteMultipartUpload must be non-empty relative paths; they are rejected if they begin with /, contain an exact .. path segment, or contain control characters.

Metadata is part of the core system, not an external catalog bolted on afterwards. Descriptions are stored as RO-Crate JSON-LD, so datasets, files, people, instruments, workflows, software, and process runs can be described in a shared format. These descriptions live in a CRDT-based triple store, which allows concurrent edits on different nodes and merges them without a single authority arbitrating the result. Management resources such as users and groups are synchronized through durable document-sync topics, which lets nodes keep working through network outages and reconcile state once they reconnect.

File contents go into a content-addressed blob layer. Objects are hashed with BLAKE3, making integrity checks and deduplication part of the storage model rather than a separate step. If the same file shows up under different paths or on different nodes, it is recognized by its content instead of its location. Replication uses Bao-tree verified streaming, so data can be checked incrementally as it arrives.

Network and research workflows

The network layer is built on iroh, which gives Aruna a peer-to-peer foundation for node discovery, authenticated communication, and direct exchange between nodes, even if they are behind NATs or firewalls.

For researchers, the data remains where it is, but becomes easier to find, describe, access, replicate and incorporate into workflows. Familiar S3 tooling keeps working, while Aruna adds shared metadata, authorization, replication, provenance, and standards-based interoperability on top of the existing infrastructure.

Aruna serves as a base layer for larger research infrastructures. Distributed full-text search, GA4GH DRS identifiers, OAI-PMH harvesting, GA4GH TES-based compute execution, CEL-based policy enforcement, event subscriptions, and transparent request forwarding all rest on the same foundation: sovereign nodes, shared metadata, verified data exchange, and open interfaces.

The goal is to support FAIR data practice in a way that matches how research actually works: distributed, collaborative, policy-bound, and owned by many parties at once.

Getting Started

The quickest way to try Aruna is a local 3-node demo deployment.

Prerequisites

For local builds:

For local test deployments:

  • curl (ss for cluster setup)
  • docker
  • docker-compose
  • just (optional, for convenience)

Run a single node with an external identity provider

Start one node with:

just local

or invoke scripts/local_deploy.sh directly.

The default example configuration exposes:

  • the REST API and Swagger UI on http://127.0.0.1:3000/swagger-ui
  • the S3 endpoint on http://127.0.0.1:1337

Evaluate a local cluster

For a quick end-to-end evaluation, run:

just local-cluster
# or
just local-cluster-oidc

This demo deployment:

  • builds the workspace in release mode
  • launches 3 local Aruna nodes
  • waits for readiness at http://127.0.0.1:<port>/swagger-ui
  • writes per-node logs, summary.txt and a private credentials.txt to target/test-deploy/
  • prints an ADMIN_TOKEN=... line for use in authenticated API calls during the session
  • prints a summary listing every node's API, portal, S3 and ops URLs next to the test logins

just preview additionally serves the portal. The portal has its own listener, so each node exposes the SPA on a separate port from the REST API; the REST port redirects / to the Swagger UI.

Useful overrides:

  • ARUNA_TEST_DEPLOY_BASE_PORT shifts the entire local port range
  • ARUNA_TEST_DEPLOY_EXIT_AFTER_READY=1 exits once the cluster is ready instead of keeping it running

Ctrl-C stops the cluster again. A deployment that outlived its terminal is stopped with:

just stop

It interrupts a deploy script that still monitors the nodes, stops every node named by a pid file under target/test-deploy/, and removes the Keycloak compose project. Logs, summary.txt and credentials.txt stay in place.

just local-cluster-oidc extends the same 3-node startup check with a local Keycloak instance.

Run a single node from source

To run a node directly from source, copy the example environment file and start the main binary from the workspace root:

cp .env.example .env
cargo run -p aruna

The default example configuration exposes:

  • the REST API and Swagger UI on http://127.0.0.1:3000/swagger-ui
  • the S3 endpoint on http://127.0.0.1:1337

State And Onboarding

A node started without an ONBOARDING_SECRET initializes a new realm on first boot and persists its identity under STORAGE_PATH. When this happens, the first management node also logs an initial local onboarding secret for the new realm.

Additional nodes join an existing realm by setting ONBOARDING_SECRET on their first boot.

Onboarding only takes effect on a fresh data directory. Once a node has persisted state, later .env changes, including a new ONBOARDING_SECRET, do not re-bootstrap or re-onboard it. To repeat an onboarding or bootstrap flow, point the node at a fresh STORAGE_PATH.

For a ready-made multi-node onboarding flow, use just local-cluster instead of walking through the onboarding APIs manually.

Durability Configuration

ARUNA_FJALL_PERSIST_MODE controls the Fjall persist mode used by Aruna's local storage engine and document-sync metadata state.

ValueDurability contract
buffer (default)Flushes data to OS buffers before local Fjall persistence returns. This keeps write latency low and protects against an application crash, but recently acknowledged writes are not guaranteed after an OS crash or power loss.
sync_allFlushes data and metadata with fsync before local Fjall persistence returns. This gives stronger local crash durability at higher write latency.

The setting does not change replication, authorization, or RO-Crate semantics. Metadata requests marked MetadataRequestDurability::WalAlreadyDurable have already been accepted by the metadata event-log phase, so document-sync projection flushes may be deferred. The event-log write and later projection flush still use the configured Fjall mode; buffer does not become fsync-durable because a request is WAL-first.

Object-backed RO-Crate imports copy the archive into a hidden seekable spool. Until that spool is deleted at the end of the import, the importing node can temporarily use roughly twice the archive's stored bytes; operators should reserve capacity accordingly.

License

Aruna is licensed under either of

at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Aruna by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Feedback & Contributions

If you have any ideas, suggestions, or issues, please don't hesitate to open an issue and/or PR. Contributions to this project are always welcome! We appreciate your help in making this project better. Please have a look at our Contributor Guidelines as well as our Code of Conduct for more information.

About

The data orchestration engine

Resources

Code of conduct

Contributing

Stars

23 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

RustLicenseLicenseCICodecovdependency status


Aruna logo


A FAIR, federated data orchestration engine

Warning

Work in progress! You are viewing the upcoming version 3. See the v2 branch for the latest stable release.

Aruna is a federated peer-to-peer data orchestration engine that enables organizations to share and organize data and metadata without handing over control to a central platform.

Features

  • Sovereign trust model: Each node belongs to one organization. Realms define shared trust between them.
  • Fine-grained access control: Path-based permissions with wildcard support and group-based roles.
  • S3-compatible API: Every node exposes an S3 API for data access.
  • Virtual buckets: Buckets are virtual collections of local and remote data resources, with configurable materialization behavior.
  • Extensible storage backends: Support for a variety of storage backends through OpenDAL.
  • Standardized metadata: Metadata is stored as RO-Crate JSON-LD enabling rich, interoperable descriptions of datasets, files, and processes.
  • Powerful metadata manipulation: RO-Crates can be created, edited and viewed through SPARQL queries and updates.
  • Distributed full-text search: Per-node Tantivy indexes with fan-out queries and authorization filtering.
  • Built-in replication and synchronization: Metadata and data are replicated across nodes with automatic conflict resolution.
  • Interoperable using open standards: OIDC for authentication, GA4GH DRS for data referencing, OAI-PMH for metadata harvesting.
  • AI assistant tools: Authenticated MCP access to Aruna context, data, metadata, and compute operations.
  • Easy deployment: Run a node as a single binary or deploy a multi-node cluster.

Architecture and Goals

Aruna is built for research data that does not live in one place, and often cannot be moved into one. Universities, institutes, labs, archives, repositories and infrastructure providers each have their own storage systems, policies, identities, and responsibilities. A central platform can be convenient, but it also creates a new point of control and tends to clash with legal, organizational, or practical constraints. Aruna takes a different approach: every participating organization runs its own node, keeps authority over its data, and still joins a shared network for discovery, access, replication, and collaboration.

The system is organized around realms. A realm is an organizational trust boundary, such as an institute, department, consortium, or project network. Each node belongs to one realm, and realms can establish trust with each other when collaboration requires it. Trust is not the same as access. A trusted partner does not automatically gain permission to read or modify data. Access stays explicit, granted through groups, roles, and path-based permissions. Data sits with the organization responsible for it, while researchers can still work across institutions.

Data, metadata, and access

Each Aruna node exposes an S3-compatible API, so researchers can keep using the tools, scripts, workflow systems, and libraries they already have instead of learning a new storage protocol. Buckets are virtual collections that mix local data, replicated data, and references to remote resources. To a user, this looks like one coherent access point. Underneath, Aruna tracks where data actually lives, which permissions apply, and whether an object should be materialized locally or fetched on demand.

Note

Object keys for PutObject, CreateMultipartUpload, UploadPart, and CompleteMultipartUpload must be non-empty relative paths; they are rejected if they begin with /, contain an exact .. path segment, or contain control characters.

Metadata is part of the core system, not an external catalog bolted on afterwards. Descriptions are stored as RO-Crate JSON-LD, so datasets, files, people, instruments, workflows, software, and process runs can be described in a shared format. These descriptions live in a CRDT-based triple store, which allows concurrent edits on different nodes and merges them without a single authority arbitrating the result. Management resources such as users and groups are synchronized through durable document-sync topics, which lets nodes keep working through network outages and reconcile state once they reconnect.

File contents go into a content-addressed blob layer. Objects are hashed with BLAKE3, making integrity checks and deduplication part of the storage model rather than a separate step. If the same file shows up under different paths or on different nodes, it is recognized by its content instead of its location. Replication uses Bao-tree verified streaming, so data can be checked incrementally as it arrives.

Network and research workflows

The network layer is built on iroh, which gives Aruna a peer-to-peer foundation for node discovery, authenticated communication, and direct exchange between nodes, even if they are behind NATs or firewalls.

For researchers, the data remains where it is, but becomes easier to find, describe, access, replicate and incorporate into workflows. Familiar S3 tooling keeps working, while Aruna adds shared metadata, authorization, replication, provenance, and standards-based interoperability on top of the existing infrastructure.

Aruna serves as a base layer for larger research infrastructures. Distributed full-text search, GA4GH DRS identifiers, OAI-PMH harvesting, GA4GH TES-based compute execution, CEL-based policy enforcement, event subscriptions, and transparent request forwarding all rest on the same foundation: sovereign nodes, shared metadata, verified data exchange, and open interfaces.

The goal is to support FAIR data practice in a way that matches how research actually works: distributed, collaborative, policy-bound, and owned by many parties at once.

Getting Started

The quickest way to try Aruna is a local 3-node demo deployment.

Prerequisites

For local builds:

For local test deployments:

  • curl (ss for cluster setup)
  • docker
  • docker-compose
  • just (optional, for convenience)

Run a single node with an external identity provider

Start one node with:

just local

or invoke scripts/local_deploy.sh directly.

The default example configuration exposes:

  • the REST API and Swagger UI on http://127.0.0.1:3000/swagger-ui
  • the S3 endpoint on http://127.0.0.1:1337

Evaluate a local cluster

For a quick end-to-end evaluation, run:

just local-cluster
# or
just local-cluster-oidc

This demo deployment:

  • builds the workspace in release mode
  • launches 3 local Aruna nodes
  • waits for readiness at http://127.0.0.1:<port>/swagger-ui
  • writes per-node logs, summary.txt and a private credentials.txt to target/test-deploy/
  • prints an ADMIN_TOKEN=... line for use in authenticated API calls during the session
  • prints a summary listing every node's API, portal, S3 and ops URLs next to the test logins

just preview additionally serves the portal. The portal has its own listener, so each node exposes the SPA on a separate port from the REST API; the REST port redirects / to the Swagger UI.

Useful overrides:

  • ARUNA_TEST_DEPLOY_BASE_PORT shifts the entire local port range
  • ARUNA_TEST_DEPLOY_EXIT_AFTER_READY=1 exits once the cluster is ready instead of keeping it running

Ctrl-C stops the cluster again. A deployment that outlived its terminal is stopped with:

just stop

It interrupts a deploy script that still monitors the nodes, stops every node named by a pid file under target/test-deploy/, and removes the Keycloak compose project. Logs, summary.txt and credentials.txt stay in place.

just local-cluster-oidc extends the same 3-node startup check with a local Keycloak instance.

Run a single node from source

To run a node directly from source, copy the example environment file and start the main binary from the workspace root:

cp .env.example .env
cargo run -p aruna

The default example configuration exposes:

  • the REST API and Swagger UI on http://127.0.0.1:3000/swagger-ui
  • the S3 endpoint on http://127.0.0.1:1337

State And Onboarding

A node started without an ONBOARDING_SECRET initializes a new realm on first boot and persists its identity under STORAGE_PATH. When this happens, the first management node also logs an initial local onboarding secret for the new realm.

Additional nodes join an existing realm by setting ONBOARDING_SECRET on their first boot.

Onboarding only takes effect on a fresh data directory. Once a node has persisted state, later .env changes, including a new ONBOARDING_SECRET, do not re-bootstrap or re-onboard it. To repeat an onboarding or bootstrap flow, point the node at a fresh STORAGE_PATH.

For a ready-made multi-node onboarding flow, use just local-cluster instead of walking through the onboarding APIs manually.

Durability Configuration

ARUNA_FJALL_PERSIST_MODE controls the Fjall persist mode used by Aruna's local storage engine and document-sync metadata state.

ValueDurability contract
buffer (default)Flushes data to OS buffers before local Fjall persistence returns. This keeps write latency low and protects against an application crash, but recently acknowledged writes are not guaranteed after an OS crash or power loss.
sync_allFlushes data and metadata with fsync before local Fjall persistence returns. This gives stronger local crash durability at higher write latency.

The setting does not change replication, authorization, or RO-Crate semantics. Metadata requests marked MetadataRequestDurability::WalAlreadyDurable have already been accepted by the metadata event-log phase, so document-sync projection flushes may be deferred. The event-log write and later projection flush still use the configured Fjall mode; buffer does not become fsync-durable because a request is WAL-first.

Object-backed RO-Crate imports copy the archive into a hidden seekable spool. Until that spool is deleted at the end of the import, the importing node can temporarily use roughly twice the archive's stored bytes; operators should reserve capacity accordingly.

License

Aruna is licensed under either of

at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Aruna by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Feedback & Contributions

If you have any ideas, suggestions, or issues, please don't hesitate to open an issue and/or PR. Contributions to this project are always welcome! We appreciate your help in making this project better. Please have a look at our Contributor Guidelines as well as our Code of Conduct for more information.

About

The data orchestration engine

Resources

Code of conduct

Contributing

Stars

23 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

RustLicenseLicenseCICodecovdependency status


Aruna logo


A FAIR, federated data orchestration engine

Warning

Work in progress! You are viewing the upcoming version 3. See the v2 branch for the latest stable release.

Aruna is a federated peer-to-peer data orchestration engine that enables organizations to share and organize data and metadata without handing over control to a central platform.

Features

  • Sovereign trust model: Each node belongs to one organization. Realms define shared trust between them.
  • Fine-grained access control: Path-based permissions with wildcard support and group-based roles.
  • S3-compatible API: Every node exposes an S3 API for data access.
  • Virtual buckets: Buckets are virtual collections of local and remote data resources, with configurable materialization behavior.
  • Extensible storage backends: Support for a variety of storage backends through OpenDAL.
  • Standardized metadata: Metadata is stored as RO-Crate JSON-LD enabling rich, interoperable descriptions of datasets, files, and processes.
  • Powerful metadata manipulation: RO-Crates can be created, edited and viewed through SPARQL queries and updates.
  • Distributed full-text search: Per-node Tantivy indexes with fan-out queries and authorization filtering.
  • Built-in replication and synchronization: Metadata and data are replicated across nodes with automatic conflict resolution.
  • Interoperable using open standards: OIDC for authentication, GA4GH DRS for data referencing, OAI-PMH for metadata harvesting.
  • AI assistant tools: Authenticated MCP access to Aruna context, data, metadata, and compute operations.
  • Easy deployment: Run a node as a single binary or deploy a multi-node cluster.

Architecture and Goals

Aruna is built for research data that does not live in one place, and often cannot be moved into one. Universities, institutes, labs, archives, repositories and infrastructure providers each have their own storage systems, policies, identities, and responsibilities. A central platform can be convenient, but it also creates a new point of control and tends to clash with legal, organizational, or practical constraints. Aruna takes a different approach: every participating organization runs its own node, keeps authority over its data, and still joins a shared network for discovery, access, replication, and collaboration.

The system is organized around realms. A realm is an organizational trust boundary, such as an institute, department, consortium, or project network. Each node belongs to one realm, and realms can establish trust with each other when collaboration requires it. Trust is not the same as access. A trusted partner does not automatically gain permission to read or modify data. Access stays explicit, granted through groups, roles, and path-based permissions. Data sits with the organization responsible for it, while researchers can still work across institutions.

Data, metadata, and access

Each Aruna node exposes an S3-compatible API, so researchers can keep using the tools, scripts, workflow systems, and libraries they already have instead of learning a new storage protocol. Buckets are virtual collections that mix local data, replicated data, and references to remote resources. To a user, this looks like one coherent access point. Underneath, Aruna tracks where data actually lives, which permissions apply, and whether an object should be materialized locally or fetched on demand.

Note

Object keys for PutObject, CreateMultipartUpload, UploadPart, and CompleteMultipartUpload must be non-empty relative paths; they are rejected if they begin with /, contain an exact .. path segment, or contain control characters.

Metadata is part of the core system, not an external catalog bolted on afterwards. Descriptions are stored as RO-Crate JSON-LD, so datasets, files, people, instruments, workflows, software, and process runs can be described in a shared format. These descriptions live in a CRDT-based triple store, which allows concurrent edits on different nodes and merges them without a single authority arbitrating the result. Management resources such as users and groups are synchronized through durable document-sync topics, which lets nodes keep working through network outages and reconcile state once they reconnect.

File contents go into a content-addressed blob layer. Objects are hashed with BLAKE3, making integrity checks and deduplication part of the storage model rather than a separate step. If the same file shows up under different paths or on different nodes, it is recognized by its content instead of its location. Replication uses Bao-tree verified streaming, so data can be checked incrementally as it arrives.

Network and research workflows

The network layer is built on iroh, which gives Aruna a peer-to-peer foundation for node discovery, authenticated communication, and direct exchange between nodes, even if they are behind NATs or firewalls.

For researchers, the data remains where it is, but becomes easier to find, describe, access, replicate and incorporate into workflows. Familiar S3 tooling keeps working, while Aruna adds shared metadata, authorization, replication, provenance, and standards-based interoperability on top of the existing infrastructure.

Aruna serves as a base layer for larger research infrastructures. Distributed full-text search, GA4GH DRS identifiers, OAI-PMH harvesting, GA4GH TES-based compute execution, CEL-based policy enforcement, event subscriptions, and transparent request forwarding all rest on the same foundation: sovereign nodes, shared metadata, verified data exchange, and open interfaces.

The goal is to support FAIR data practice in a way that matches how research actually works: distributed, collaborative, policy-bound, and owned by many parties at once.

Getting Started

The quickest way to try Aruna is a local 3-node demo deployment.

Prerequisites

For local builds:

For local test deployments:

  • curl (ss for cluster setup)
  • docker
  • docker-compose
  • just (optional, for convenience)

Run a single node with an external identity provider

Start one node with:

just local

or invoke scripts/local_deploy.sh directly.

The default example configuration exposes:

  • the REST API and Swagger UI on http://127.0.0.1:3000/swagger-ui
  • the S3 endpoint on http://127.0.0.1:1337

Evaluate a local cluster

For a quick end-to-end evaluation, run:

just local-cluster
# or
just local-cluster-oidc

This demo deployment:

  • builds the workspace in release mode
  • launches 3 local Aruna nodes
  • waits for readiness at http://127.0.0.1:<port>/swagger-ui
  • writes per-node logs, summary.txt and a private credentials.txt to target/test-deploy/
  • prints an ADMIN_TOKEN=... line for use in authenticated API calls during the session
  • prints a summary listing every node's API, portal, S3 and ops URLs next to the test logins

just preview additionally serves the portal. The portal has its own listener, so each node exposes the SPA on a separate port from the REST API; the REST port redirects / to the Swagger UI.

Useful overrides:

  • ARUNA_TEST_DEPLOY_BASE_PORT shifts the entire local port range
  • ARUNA_TEST_DEPLOY_EXIT_AFTER_READY=1 exits once the cluster is ready instead of keeping it running

Ctrl-C stops the cluster again. A deployment that outlived its terminal is stopped with:

just stop

It interrupts a deploy script that still monitors the nodes, stops every node named by a pid file under target/test-deploy/, and removes the Keycloak compose project. Logs, summary.txt and credentials.txt stay in place.

just local-cluster-oidc extends the same 3-node startup check with a local Keycloak instance.

Run a single node from source

To run a node directly from source, copy the example environment file and start the main binary from the workspace root:

cp .env.example .env
cargo run -p aruna

The default example configuration exposes:

  • the REST API and Swagger UI on http://127.0.0.1:3000/swagger-ui
  • the S3 endpoint on http://127.0.0.1:1337

State And Onboarding

A node started without an ONBOARDING_SECRET initializes a new realm on first boot and persists its identity under STORAGE_PATH. When this happens, the first management node also logs an initial local onboarding secret for the new realm.

Additional nodes join an existing realm by setting ONBOARDING_SECRET on their first boot.

Onboarding only takes effect on a fresh data directory. Once a node has persisted state, later .env changes, including a new ONBOARDING_SECRET, do not re-bootstrap or re-onboard it. To repeat an onboarding or bootstrap flow, point the node at a fresh STORAGE_PATH.

For a ready-made multi-node onboarding flow, use just local-cluster instead of walking through the onboarding APIs manually.

Durability Configuration

ARUNA_FJALL_PERSIST_MODE controls the Fjall persist mode used by Aruna's local storage engine and document-sync metadata state.

ValueDurability contract
buffer (default)Flushes data to OS buffers before local Fjall persistence returns. This keeps write latency low and protects against an application crash, but recently acknowledged writes are not guaranteed after an OS crash or power loss.
sync_allFlushes data and metadata with fsync before local Fjall persistence returns. This gives stronger local crash durability at higher write latency.

The setting does not change replication, authorization, or RO-Crate semantics. Metadata requests marked MetadataRequestDurability::WalAlreadyDurable have already been accepted by the metadata event-log phase, so document-sync projection flushes may be deferred. The event-log write and later projection flush still use the configured Fjall mode; buffer does not become fsync-durable because a request is WAL-first.

Object-backed RO-Crate imports copy the archive into a hidden seekable spool. Until that spool is deleted at the end of the import, the importing node can temporarily use roughly twice the archive's stored bytes; operators should reserve capacity accordingly.

License

Aruna is licensed under either of

at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Aruna by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Feedback & Contributions

If you have any ideas, suggestions, or issues, please don't hesitate to open an issue and/or PR. Contributions to this project are always welcome! We appreciate your help in making this project better. Please have a look at our Contributor Guidelines as well as our Code of Conduct for more information.

About

The data orchestration engine

Resources

Code of conduct

Contributing

Stars

23 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages