Skip to content
Back to skills

Ovstorage User Choose A Backend

DSecurity

Use when selecting the right ovstorage backend plugin for a task or deciding which route to configure.

  • 15 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 19, 2026
devopsrustgoawsazuregitapibackend

Works with

  • cli
  • api
  • mcp

Security analysis

D50/100
  • criticalAccesses sensitive system or user directories
  • criticalAccesses sensitive system or user directories

Pro shows the line behind each finding and how to fix it

Scanned October 19, 2026

npx -y skills add NVIDIA-Omniverse/ovstorage --skill ovstorage-user-choose-a-backend --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Ovstorage User Choose A Backend?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Ovstorage User Choose A Backend
[![Security: D — Skills Directory](https://www.skillsdirectory.com/api/skills/nvidia-omniverse-ovstorage-user-choose-a-backend/badge)](https://www.skillsdirectory.com/skills/nvidia-omniverse-ovstorage-user-choose-a-backend)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: ovstorage-user-choose-a-backend
description: Use when selecting the right ovstorage backend plugin for a task or deciding which route to configure.
license: CC-BY-4.0
version: "0.1.0"
author: NVIDIA Omniverse
tags: [ovstorage, routing, backend]
tools: [Read]
compatibility: Requires ovstorage MCP tools or equivalent library calls. Backend-specific plugins and credentials are user-supplied.
---

# Choose a Backend

## Goal

Pick a backend kind whose address shape, capabilities, and credential model
match the storage task.

## Available backends

| Backend | Use when | Address shape | Notes |
|---|---|---|---|
| `file` | Data is on a local or mounted filesystem visible to this process | `file:///absolute/path` | Best for local smoke tests, dev fixtures, and direct POSIX semantics. |
| `http` | Data is read from an HTTP(S) endpoint | `https://host/path` | Read-oriented and URL-shaped; confirm write/list support before depending on it. |
| `omniverse-storage-service` | Targeting a deployed Omniverse Storage Service | gRPC; configured via `address` | Needs `address` — either a discovery root (host of `/api/v1/services` and `/api/v1/auth-config`) with OIDC credentials, or a `grpc://` / `grpcs://` storage endpoint dialed directly. See per-backend section below. |
| `s3` | AWS S3 or S3-compatible object stores (MinIO, R2, B2, custom endpoint) | `s3://<bucket>/<key>` | `aws_access_key_id` + `aws_secret_access_key` (+ optional `aws_session_token`); env vars and `~/.aws/credentials` honoured. |
| `gcs` | Google Cloud Storage | `gs://<bucket>/<object>` | `service_account_key` (JSON blob) or ADC `file_path`; accepts `service_account`, `authorized_user`, `external_account` (WIF), and `impersonated_service_account` JSON; no IMDS. |
| `azure` | Azure Blob and ADLS Gen2 (HNS-aware accounts) | `azure://<account>/<container>/<path>` | One of `account_key`, `sas_token`, service principal, or workload identity. |
| `huggingface` | Hugging Face Hub repositories, read-only (models, datasets, spaces) | `hf://{models\|datasets\|spaces}/<namespace>/<name>/<path>` (optional `?revision=<ref>` pin); under an `alias` layer also the Hub's own `https://huggingface.co/<namespace>/<name>/<path>` URL | Single `token` (descriptor default `${HF_TOKEN}`); anonymous serves public repositories. |
| `opendal` | Long-tail backends fronted by OpenDAL (services compiled in: `fs`, `s3`, `webdav`) | `opendal://<service>/<path>` (configurable prefix) | Driver-specific; `s3` uses bare `access_key_id` / `secret_access_key`, `webdav` uses `password`. |
| `nucleus` | NVIDIA Omniverse Nucleus content-collaboration server | `omniverse://server[:port]/path` (with optional `?<branch>&<checkpoint>` selector) | Three credential methods (`sso`, `userpass`, `api_token`); refresh token persisted in OS keyring for warm-continue. |
| `broker` | Routing traffic through an upstream `ovstorage-broker` daemon (per-call authz, broker-side caching, credential isolation) | No scheme of its own — address roots are published by the upstream broker (typically `s3://`, `gs://`, `azure://`, `omniverse://`, `file://`) | Single config key `address` (HTTPS discovery, direct gRPC, UDS, or named pipe). One credential method: `client_credentials` (OIDC client ID + secret) for headless deployments; interactive PKCE / device flow drives via `Factory::authenticate`. |

## Backend-specific notes

### `omniverse-storage-service`

A Omniverse Storage Service deployment, accessed over gRPC with
OIDC bearer-token auth. Configure with:

- `address` — where the service is. Either an HTTP root that serves
  `/api/v1/services` and `/api/v1/auth-config`, from which the plugin
  discovers the gRPC endpoint and the OIDC client; or a `grpc://` /
  `grpcs://` storage endpoint, dialed directly with no discovery
  service and no OIDC.
- `oidc_client_name` (optional, default `"default"`) — picks an entry
  from `auth-config.clients`.

Credentials arrive via OAuth (PKCE for browser, device flow for
headless). See
[`ovstorage-user-authenticate-to-backend`](../ovstorage-user-authenticate-to-backend/SKILL.md)
for the auth flow.

Pick this backend when you have an existing Omniverse Storage Service deployment;
otherwise pick a cloud or file backend.

This backend connects to an existing service deployment. Configure its
endpoint and credentials using the client plugin guide linked below.

### `s3`

AWS S3 and S3-compatible object stores. Addresses are
`s3://<bucket>/<key>`; the configured `bucket` is authoritative, so
the prefix lives in the address, not the connection config. Config
keys:

- `bucket` (**required**) and `region` (**required**).
- `endpoint` — optional; required for `minio`, `b2`, and `custom`
  compatibility profiles.
- `compatibility_profile` — enum (`aws`, `minio`, `r2`, `b2`,
  `custom`; defaults to `aws`, or `custom` when `endpoint` is set).
  Selects addressing style and signing region per the matrix in
  [`plugin-s3.md`](../../docs/public/plugin-storage/plugin-s3.md);
  this is the knob to flip for R2 (`auto` signing region) or B2
  (path-style + `auto`).
- `force_path_style` (bool), `force_request_payer` (bool),
  `profile` (named entry in the AWS shared credentials file).
- `sqs_queue_url` / `sqs_max_messages` / `sqs_wait_seconds` /
  `sqs_visibility_timeout` for `watch_directory`.

Credentials (`aws_access_key_id`, `aws_secret_access_key`,
`aws_session_token`) are all optional; absent fields fall through
the chain (env vars, then the AWS shared credentials file). IMDS,
AWS SSO, and STS role assumption are **not** implemented — operators
materialise a static-key profile out-of-band.

### `gcs`

Google Cloud Storage. Addresses are `gs://<bucket>/<object>`. Config
keys:

- `bucket` (**required**).
- `project_id` — optional; surfaced for operator clarity only.
- `service_account` — optional; named entry in the credential chain.
- `endpoint` — optional; for GCS-compatible deployments (e.g.
  `fake-gcs-server`).
- `pubsub_subscription` /  `pubsub_pull_max` for `watch_directory`.

Credentials are `service_account_key` (an ADC JSON blob of `type:
service_account`, `authorized_user`, `external_account`, or
`impersonated_service_account`) or `file_path` (ADC JSON file on
disk, same four types; defaults to
`~/.config/gcloud/application_default_credentials.json`).
Only `service_account` creds can mint V4 signed URLs; reads under
every other credential type pull bytes through the JSON download
endpoint instead. The GCE/GKE metadata server, the AWS /
`executable` `external_account` source flavors, and workforce
(user-identity) federation are not implemented in-process.

### `azure`

Azure Blob and Azure Data Lake Storage Gen2 (HNS-aware). Addresses
are `azure://<account>/<container>/<path>`. The Azure plugin
**rejects unknown config keys** (`CONFIG_KEYS` is a strict
whitelist), so don't add a `prefix` field. Config keys:

- `account` (**required**) and `container` (**required**).
- `endpoint_suffix` — optional; default `core.windows.net` (override
  for sovereign clouds).
- `blob_endpoint` — optional full blob-tier URL (scheme, host, port,
  path prefix); overrides `endpoint_suffix` for that tier. Use
  `https://` for real custom, private-link and sovereign endpoints.
  `http://127.0.0.1:10000/devstoreaccount1` is the **Azurite emulator**
  form and is emulator-only.
- `dfs_endpoint` — the same for the ADLS Gen2 `dfs` tier. May be set
  on its own (the blob tier then stays on `endpoint_suffix`); an HNS
  connection that sets `blob_endpoint` must set this too.
- **Prefer `https://`.** A plain-`http://` endpoint is accepted with
  any credential mode and on any host — `http://azurite:10000` is a
  supported emulator shape, and needs no extra key. On a non-loopback
  host the connection logs a `warn`, because object bytes and metadata
  cross the link in the clear, a caller `sas_token` is readable in the
  request URL, an OAuth token in the `Authorization` header, and the
  redirect-following read and write paths hand out a five-minute
  Service SAS that can travel in the clear. Use `http://` only for an
  emulator; for real custom, private-link and sovereign endpoints use
  `https://`.
- `hierarchical_namespace` — bool; set to `true` for ADLS Gen2 HNS
  accounts. `instantiate` checks this matches the account's actual
  mode.
- `change_feed_enabled` / `change_feed_segment_lag_seconds` /
  `change_feed_poll_interval_seconds` for `watch_directory` (flat
  Blob accounts only).

Credentials are picked from four distinct methods, in this
resolution order: `account_key` (Shared Key signing) → `sas_token`
(appended verbatim) → workload identity (`federated_token_file` +
`client_id` + `tenant_id`) → service principal (`client_id` +
`client_secret` + `tenant_id`). Managed Identity / IMDS, Azure CLI
session reuse, and the rest of the `DefaultAzureCredential` chain
are not implemented in-process.

### `huggingface`

Hugging Face Hub repositories, **read-only**. One connection serves
one repository; addresses are
`hf://{models|datasets|spaces}/<namespace>/<name>/<path>`, with an
optional `?revision=<ref>` query pinning any address to a git
revision. When an `alias` layer sits above the backend, the Hub's own
repository URL resolves as well — `https://` or `http://`, on
`huggingface.co`, `www.huggingface.co` or `hf.co`, prefixed `datasets/` or
`spaces/` for those repository types — with `?revision=` carrying
through; the Hub's `/blob/`, `/resolve/` and `/tree/` web-view links are
not unwrapped. Config keys:

- `repo_id` (**required**; `namespace/name`).
- `repo_type` — optional; `model` (default), `dataset`, or `space`.
- `revision` — optional; the connection's default revision
  (default `main`).

The single credential is `token` (a `hf_…` access token; read scope
is sufficient), with a descriptor default of `${HF_TOKEN}`; an empty
bundle connects anonymously and serves public repositories. Writes,
deletes, metadata updates, and directory watches all answer
`Unsupported`; version listing walks the repository's commit history.

### `opendal`

Long-tail backends fronted by Apache OpenDAL. Pick a `service` —
the descriptor's enum advertises **only** the services this workspace
compiles in, namely `fs`, `s3`, and `webdav`. Other OpenDAL services
(http, sftp, hdfs, etc.) are not enabled and will be rejected at
`instantiate`. Config keys:

- `service` (**required** enum: `fs` | `s3` | `webdav`).
- `endpoint` — optional; passed through to the chosen driver.
- `config_json` — optional flat JSON string-map of driver knobs
  (`bucket`, `region`, `root`, `username`, ...).
- `prefix` — optional URL; route prefix shown to callers (defaults
  to `opendal://<service>/`).

Credentials are a fixed shared set: `access_key_id` +
`secret_access_key` (for the OpenDAL `s3` driver), `password` (for
WebDAV), and `private_key`. Note that the OpenDAL `s3` driver uses
the **bare** `access_key_id` / `secret_access_key` names — not the
`aws_*`-prefixed names that the first-party `s3` plugin uses — so
the credential shapes are not interchangeable. For S3-shaped
storage that needs the full conditional-write / version-listing
capability set, prefer the first-party `s3` plugin.

### `nucleus`

NVIDIA Omniverse Nucleus is the content-collaboration server for
the Omniverse platform. Pick this backend when:

- You have an Omniverse Nucleus server deployed (`omniverse://`
  URLs).
- You need checkpoint-based versioning (Nucleus tracks per-path
  checkpoint history; `list_versions` enumerates them newest-first
  and an `?&<checkpoint>` URL selector pins reads to a specific
  checkpoint).
- You need ACL-aware permissions on `stat`
  (`populates_effective_permissions_on_stat = true`).

Configuration is minimal: `server` (the `host[:port]` of the
Nucleus server) is the only required key. `endpoint` overrides
SOWS discovery for production session establishment; `prefix`
scopes which paths the backend instance serves (default `/`);
`use_lft` (default `true`) gates the LFT redirect path for bulk
bytes.

`if_match` on this backend is an opaque etag string — Nucleus's
mutating omni1 method that carries a conditional (`update_asset`)
accepts only an etag. Pass `if_match: Some(etag_string)`. The
checkpoint selector lives in the URL (`?&<N>`), not in `if_match`.

See [`ovstorage-user-authenticate-to-backend`](../ovstorage-user-authenticate-to-backend/SKILL.md)
for the three credential methods (`sso`, `userpass`, `api_token`)
and the keyring-backed refresh-token warm-continue.

### `broker`

Routes traffic through an upstream `ovstorage-broker` daemon. The
broker holds long-lived cloud credentials, enforces per-call
authorization, runs broker-side metadata + byte caching, and keeps
credentials off the calling host. Pick this backend when:

- You want a credential boundary: the calling process holds only
  short-lived broker bearers, not S3 / GCS / Azure keys.
- You want per-call authorization (allow / deny / audit) against a
  configured built-in authorization policy.
- You're running zero-trust fleets, workload-identity-federated
  deployments, or want a shared metadata cache in front of the
  cloud.

Configuration is minimal: `address` (broker discovery URL or direct
gRPC endpoint) is the only required key. Accepted shapes:

- `https://broker.example.com` — HTTPS discovery (fetches
  `/api/v1/services` for the broker endpoint).
- `http://localhost` — plaintext-HTTP discovery (honored only for
  `localhost`, IP literals, and `.local` hosts).
- `grpc+tls://host:port` / `grpc+tcp://host:port` — direct gRPC,
  skipping discovery.
- `/path/to/socket` — Unix domain socket.
- `pipe:NAME` — Windows named pipe.

Optional `oidc_client_name` (default `"default"`) selects an entry
from the broker's published `auth-config.clients.<name>` when the
deployment publishes auth-config under a non-default key.

Address roots come from the broker on `ListAddressRoots` after
`instantiate`. The library merges them into the routing table; the
per-route capability profile mirrors the upstream plugin's profile
field-by-field (so a brokered `s3://corp-prod/` route advertises
the same `supports_recursive_list`, `supports_version_listing`,
`version_list_order`, `watch_directory_kinds`,
`redirect_size_threshold`, etc. it would in Direct mode).

See [`ovstorage-user-authenticate-to-backend`](../ovstorage-user-authenticate-to-backend/SKILL.md)
for the `client_credentials` credential method and the
broker-driven interactive PKCE / device flow.

## Recipe

1. Run [`ovstorage-user-getting-started`](../ovstorage-user-getting-started/SKILL.md) and confirm
   the backend kind appears in `backend_kinds`. That list is the layers this
   stack declares, so a kind you know the library supports — `file` included —
   is absent until the config declares a layer for it.
2. Match the address root you need to the backend's URL scheme and configured
   `address_roots`. A public `s3://`, `gs://` or `azure://` address may be
   readable with no route of its own when the host grants an anonymous
   fallback for that scheme — read-only, and anonymous in the strict sense
   (no credential of any kind is attached); the sign is a hidden `s3:///`
   root in the doctor report. Every mutation through it answers
   `Unsupported`, so configure a connection when you need to write.
3. Check capabilities before relying on writes, recursive list, directory
   delete, watches, or optimistic concurrency.
4. Follow [`ovstorage-user-authenticate-to-backend`](../ovstorage-user-authenticate-to-backend/SKILL.md)
   before first use if the descriptor has credential fields.

## References

- [`docs/public/library-rust/README.md`](../../docs/public/library-rust/README.md) for route
  and connection setup.
- [`docs/public/plugin-storage/README.md`](../../docs/public/plugin-storage/README.md) for
  plugin capability vocabulary.
- [`plugin-file`](../../docs/public/plugin-storage/plugin-file.md)
  and [`plugin-http`](../../docs/public/plugin-storage/plugin-http.md)
  for backend-specific semantics.
- [`plugin-services-client`](../../docs/public/plugin-storage/plugin-services-client.md)
  for the `omniverse-storage-service` backend.
- [`plugin-s3.md`](../../docs/public/plugin-storage/plugin-s3.md) for
  AWS S3 and S3-compatible object stores.
- [`plugin-gcs.md`](../../docs/public/plugin-storage/plugin-gcs.md)
  for Google Cloud Storage.
- [`plugin-azure.md`](../../docs/public/plugin-storage/plugin-azure.md)
  for Azure Blob and ADLS Gen2.
- [`plugin-opendal.md`](../../docs/public/plugin-storage/plugin-opendal.md)
  for OpenDAL-fronted long-tail backends.
- [`plugin-nucleus.md`](../../docs/public/plugin-storage/plugin-nucleus.md)
  for the Omniverse Nucleus content-collaboration server.
- [`plugin-broker.md`](../../docs/public/plugin-storage/plugin-broker.md)
  for the broker-client cdylib.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.