What you'll learn

  • What OASIS providers are and the full provider catalogue
  • Configure auto-failover, load balancing and auto-replication
  • Switch providers at runtime from your app code
  • Deploy an ONODE (the OASIS backend) to Railway and Docker
  • Environment variables, secrets management and OASIS config
  • Production security: JWT expiry, CORS, rate limiting
  • Monitoring and health checks

The OASIS Provider Model

Every storage, blockchain and identity operation in OASIS goes through a provider — a pluggable adapter that translates OASIS API calls into the native operations of a specific network or database. Your app code never calls Solana, MongoDB or Holochain directly; it calls the OASIS API and the active provider handles the rest.

This gives you three powerful capabilities out of the box:

Provider Catalogue

ProviderTypeBest forStatus
MongoDBOASISDatabaseFast structured data, default for most appsLive
HoloOASISP2P / DHTTruly decentralised, agent-centric dataLive
IPFSOASISFile / ContentImmutable content addressing, large assetsLive
SolanaOASISBlockchainNFTs, tokens, on-chain proofsLive
EthereumOASISBlockchainEVM smart contracts, ERC-721/1155 NFTsLive
EOSIOasisOASISBlockchainHigh-throughput EOSIO/SEEDS transactionsLive
Neo4jOASISGraph DBComplex relationship queries, social graphsLive
SQLLiteDBOASISDatabaseLocal / edge deployments, offline-firstLive
ThreeFoldOASISDecentralised computeSovereign hosting, ThreeFold gridLive
AzureCosmosDBOASISCloud DBEnterprise Azure deploymentsLive
ActivityPubOASISFederationFediverse / Mastodon integrationBeta
ChainlinkOASISOracleReal-world data feeds, price oraclesBeta

Configuring Providers in Your ONODE

The OASIS ONODE reads provider config from appsettings.json. Here's a production-ready example with MongoDB as primary and Holochain as failover:

appsettings.json
{
  "OASIS": {
    "StorageProviders": {
      "MongoDBOASIS": {
        "ConnectionString": "${MONGO_CONNECTION_STRING}",
        "DBName": "oasis_prod",
        "Priority": 1        // ← primary provider
      },
      "HoloOASIS": {
        "HolochainConductorURI": "ws://localhost:8888",
        "Priority": 2        // ← first failover
      },
      "IPFSOASIS": {
        "IPFSNode": "https://ipfs.infura.io:5001",
        "Priority": 3        // ← second failover
      }
    },
    "AutoFailOver":      true,
    "AutoReplication":   true,   // write to all providers
    "AutoLoadBalance":   true,   // reads from fastest provider
    "DefaultProvider":  "MongoDBOASIS",

    "JWT": {
      "Secret":            "${JWT_SECRET}",
      "ExpiresInDays":      7,
      "RefreshExpiresInDays": 30
    }
  }
}
⚠️
Never commit secrets

Use ${ENV_VAR} syntax in appsettings.json to reference environment variables. Never commit real connection strings, JWT secrets or API keys to source control. Use Railway / Docker secrets or a vault like HashiCorp Vault for production.

Switching Providers at Runtime

You can override the active provider on a per-request basis from your JavaScript app:

javascript
import { oasis } from './oasis.js';

// Switch the global default for subsequent calls
await oasis.provider.setGlobalDefaultProvider({ providerType: 'HoloOASIS' });

// Or override just for a single request (non-global)
const result = await oasis.data.saveHolon({
  name:         'SensitiveRecord',
  metaData:     { secret: 'data' },
  providerType: 'HoloOASIS',   // only this request uses Holochain
  setGlobally:  false
});

// List all registered providers and their status
const { result: providers } = await oasis.provider.getProviders();
providers.forEach(p => console.log(p.providerType, p.status, p.priority));

Deploying an ONODE to Railway

Railway is the fastest way to deploy a production ONODE — it handles SSL, custom domains and environment variables automatically.

1

Fork and connect the repo

Fork NextGenSoftwareUK/OASIS to your GitHub account. In Railway, click New Project → Deploy from GitHub and select your fork. Choose the ONODE/NextGenSoftware.OASIS.API.ONODE.WebAPI directory as the root.

2

Set environment variables

railway env vars
MONGO_CONNECTION_STRING = mongodb+srv://user:pass@cluster.mongodb.net/oasis_prod
JWT_SECRET              = your-256-bit-random-secret
OASIS__DefaultProvider  = MongoDBOASIS
OASIS__AutoFailOver     = true
OASIS__AutoReplication  = false   # enable when you have 2+ providers
ASPNETCORE_ENVIRONMENT  = Production
3

Set the start command

railway start command
dotnet NextGenSoftware.OASIS.API.ONODE.WebAPI.dll
4

Custom domain

In Railway → Settings → Domains, add your custom domain (e.g. api.myapp.com). Railway provisions Let's Encrypt SSL automatically. Point your OASIS SDK at this URL:

javascript
const oasis = new OASISClient({ baseUrl: 'https://api.myapp.com' });

Deploying with Docker

For self-hosted or enterprise deployments, use the official Docker setup:

docker-compose.yml
version: '3.9'

services:
  onode:
    image: nextgensoftware/oasis-onode:latest
    ports:
      - "80:80"
      - "443:443"
    environment:
      - MONGO_CONNECTION_STRING=${MONGO_CONNECTION_STRING}
      - JWT_SECRET=${JWT_SECRET}
      - OASIS__DefaultProvider=MongoDBOASIS
      - OASIS__AutoFailOver=true
      - ASPNETCORE_ENVIRONMENT=Production
    volumes:
      - ./appsettings.json:/app/appsettings.json
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/api/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  mongo:
    image: mongo:7
    volumes:
      - mongo_data:/data/db
    environment:
      MONGO_INITDB_ROOT_USERNAME: ${MONGO_USER}
      MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASS}

volumes:
  mongo_data:
terminal
docker compose up -d
✓ Container onode   Started
✓ Container mongo   Started

# Verify health
curl https://api.myapp.com/api/health
{"status":"Healthy","providers":{"MongoDBOASIS":"Connected"}}

Production Security Checklist

🔒
Before going live
  • JWT secret — use a cryptographically random 256-bit value; rotate it every 90 days
  • CORS — set AllowedOrigins in appsettings to your actual domains; never use * in production
  • Rate limiting — enable the built-in rate limiter (OASIS__RateLimiting__Enabled: true); default is 100 req/min per IP
  • HTTPS only — set ASPNETCORE_URLS=https://+:443 and redirect HTTP → HTTPS
  • Password policy — the OASIS avatar system enforces minimum 8 chars + complexity by default; don't disable this
  • Admin endpoints — endpoints like /api/avatar/get-all-avatars require [Authorize] and admin role; verify your role config
  • MongoDB — use a dedicated database user with least-privilege access; enable MongoDB Atlas IP allowlisting
  • Secrets — use Railway secrets, Docker secrets or HashiCorp Vault; never put real values in appsettings.json

Health & Monitoring

The ONODE exposes a health endpoint and a stats endpoint for monitoring:

javascript
// Health check (no auth required — safe to expose)
const health = await oasis.health.getHealthInfo();
console.log(health.result.status);           // 'Healthy' | 'Degraded' | 'Unhealthy'
console.log(health.result.providers);         // { MongoDBOASIS: 'Connected', ... }

// Platform stats
const stats = await oasis.stats.getStats();
console.log(stats.result.totalAvatars);
console.log(stats.result.totalHolons);
console.log(stats.result.totalNFTs);
📊
Recommended monitoring stack

Point Uptime Robot or Better Stack at https://api.myapp.com/api/health for uptime alerts. For detailed metrics, the ONODE emits OpenTelemetry traces — connect to Grafana Cloud or Datadog by setting OTEL_EXPORTER_OTLP_ENDPOINT in your environment.

Building a Custom Provider

If you need to integrate OASIS with a database or chain that isn't in the catalogue, you can build your own provider by implementing the IOASISStorageProvider interface in C#:

csharp (skeleton)
using NextGenSoftware.OASIS.API.Core.Interfaces;
using NextGenSoftware.OASIS.API.Core.Enums;

public class MyCustomOASIS : IOASISStorageProvider
{
    public ProviderType ProviderType => ProviderType.Custom;
    public string ProviderName    => "MyCustomOASIS";

    public async Task<OASISResult<IHolon>> SaveHolonAsync(IHolon holon, ...)
    {
        // Write holon to your custom backend
        var id = await _myDb.UpsertAsync(holon);
        holon.Id = id;
        return new OASISResult<IHolon>(holon);
    }

    public async Task<OASISResult<IHolon>> LoadHolonAsync(Guid id, ...)
    {
        var doc = await _myDb.GetAsync(id);
        return new OASISResult<IHolon>(MapToHolon(doc));
    }

    // ... implement remaining interface methods
}

Register your provider in Program.cs or via the OASIS provider registration API, and it becomes available as providerType: 'Custom' in all SDK calls. See the Providers directory in the main repo for full examples.

You've Completed the Series!

🎉
Congratulations

You've worked through all 8 modules — from your first API call to a production-deployed ONODE with multi-provider failover, GeoNFTs, quests and a published OApp. You're now equipped to build anything on the OASIS platform.

What to explore next