/api/rke/session

GET

Creates a new RKE session by performing DKE (Distributed Key Exchange) with RAIDA servers to derive an encryption key for the specified Content Server.

Description

This endpoint creates an encrypted session with a Content Server using the DKE (Distributed Key Exchange) protocol. The process involves:

DKE Protocol Steps
  1. DNS Discovery: Query the domain's DNS for RKE configuration
  2. Key Share Collection: Send get_keyshare requests to 25 RAIDA servers
  3. Key Derivation: XOR all received key shares together
  4. Key Expansion: Use HKDF-Expand to derive a 256-bit AES key
  5. Session Creation: Store the key in a session with unique ID
Requirements
  • The wallet must contain at least one authenticated coin for RAIDA encryption
  • At least 13 RAIDA servers must respond with valid key shares
  • The Content Server domain must have valid RKE DNS records
Key Caching

Derived keys are cached locally (default 24 hours TTL). If a valid cached key exists for the domain, it will be used instead of performing a new DKE operation, significantly improving performance.

Parameters

domain
string (query)
Required

The Content Server domain to create a session with.

Format: Fully qualified domain name (FQDN)

Examples:

  • content.cloudcoin.global
  • media.example.com
wallet_path
string (query)
Required

Absolute path to the wallet containing coins for RAIDA authentication.

Format: Absolute filesystem path

Examples:

  • Windows: D:/CloudCoin/Wallets/Default or D:\CloudCoin\Wallets\Default
  • Linux/macOS: /home/user/CloudCoin/Wallets/Default

Note: URL-encode the path if it contains special characters. Forward slashes work on all platforms.

Response

Returns the created session details including the session ID needed for encrypt/decrypt operations.

Response Properties (Success)

command string
Always "rke_session_create".
success boolean
True if session was created successfully.
session_id string
32-character hexadecimal session identifier. Save this value - you'll need it for all encrypt/decrypt operations.
domain string
The Content Server domain this session is for.
cs_id string
Content Server ID from DNS records.
expires_at string
ISO 8601 timestamp when the session expires (default: 1 hour from creation).
from_cache boolean
True if the key was loaded from cache instead of performing DKE.

Example Response (Success)

{
  "command": "rke_session_create",
  "success": true,
  "session_id": "a1b2c3d4e5f67890a1b2c3d4e5f67890",
  "domain": "content.cloudcoin.global",
  "cs_id": "CLOUDCOIN_CONTENT",
  "expires_at": "2025-11-30T11:00:00Z",
  "from_cache": false
}

Example Response (Error - DNS Discovery Failed)

{
  "error": true,
  "message": "DNS discovery failed",
  "code": 500,
  "result_code": 13
}

Complete Workflow Example

Here's a typical workflow for using RKE sessions:

const API_HOST = 'http://localhost:8080';
const DOMAIN = 'content.cloudcoin.global';
const WALLET = 'D:/CloudCoin/Wallets/Default';

// Step 1: Create a session
async function createSession() {
    const url = `${API_HOST}/api/rke/session?domain=${DOMAIN}&wallet_path=${encodeURIComponent(WALLET)}`;
    const response = await fetch(url);
    const result = await response.json();

    if (!result.success) {
        throw new Error(result.message);
    }

    console.log(`Session created: ${result.session_id}`);
    console.log(`Expires: ${result.expires_at}`);
    console.log(`From cache: ${result.from_cache}`);

    return result.session_id;
}

// Step 2: Encrypt data
async function encryptData(sessionId, plaintext) {
    // Convert plaintext to base64
    const base64 = btoa(plaintext);
    const url = `${API_HOST}/api/rke/encrypt?session_id=${sessionId}&plaintext=${encodeURIComponent(base64)}`;

    const response = await fetch(url);
    const result = await response.json();

    return {
        ciphertext: result.ciphertext,
        nonce: result.nonce
    };
}

// Step 3: Decrypt data
async function decryptData(sessionId, ciphertext, nonce) {
    const url = `${API_HOST}/api/rke/decrypt?session_id=${sessionId}&ciphertext=${encodeURIComponent(ciphertext)}&nonce=${nonce}`;

    const response = await fetch(url);
    const result = await response.json();

    // Decode from base64
    return atob(result.plaintext);
}

// Usage
async function main() {
    const sessionId = await createSession();

    // Encrypt a message
    const encrypted = await encryptData(sessionId, 'Hello, Content Server!');
    console.log('Encrypted:', encrypted);

    // Decrypt it back
    const decrypted = await decryptData(sessionId, encrypted.ciphertext, encrypted.nonce);
    console.log('Decrypted:', decrypted);
}

main();

Examples

JavaScript (fetch)

const API_HOST = 'http://localhost:8080';

async function createRkeSession(domain, walletPath) {
    const params = new URLSearchParams({
        domain: domain,
        wallet_path: walletPath
    });

    const response = await fetch(`${API_HOST}/api/rke/session?${params}`);
    const result = await response.json();

    if (result.success) {
        // Store session ID for later use
        sessionStorage.setItem('rke_session_id', result.session_id);
        sessionStorage.setItem('rke_expires_at', result.expires_at);

        console.log('Session created successfully');
        console.log(`Session ID: ${result.session_id}`);
        return result.session_id;
    } else {
        throw new Error(result.message);
    }
}

// Create session for a Content Server
createRkeSession(
    'content.cloudcoin.global',
    'D:/CloudCoin/Wallets/Default'
);

cURL

# Create RKE session (Windows path)
curl "http://localhost:8080/api/rke/session?domain=content.cloudcoin.global&wallet_path=D%3A%2FCloudCoin%2FWallets%2FDefault"

# Create RKE session (Linux path)
curl "http://localhost:8080/api/rke/session?domain=content.cloudcoin.global&wallet_path=%2Fhome%2Fuser%2FCloudCoin%2FWallets%2FDefault"

# Extract session ID
curl "http://localhost:8080/api/rke/session?domain=content.cloudcoin.global&wallet_path=D%3A%2FCloudCoin%2FWallets%2FDefault" | jq -r '.session_id'

Go

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
    "net/url"
)

const ApiHost = "http://localhost:8080"

type SessionCreateResponse struct {
    Command   string `json:"command"`
    Success   bool   `json:"success"`
    SessionID string `json:"session_id"`
    Domain    string `json:"domain"`
    CsID      string `json:"cs_id"`
    ExpiresAt string `json:"expires_at"`
    FromCache bool   `json:"from_cache"`
}

func CreateRkeSession(domain, walletPath string) (*SessionCreateResponse, error) {
    apiUrl := fmt.Sprintf("%s/api/rke/session?domain=%s&wallet_path=%s",
        ApiHost,
        url.QueryEscape(domain),
        url.QueryEscape(walletPath))

    resp, err := http.Get(apiUrl)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    body, _ := ioutil.ReadAll(resp.Body)
    var result SessionCreateResponse
    json.Unmarshal(body, &result)
    return &result, nil
}

func main() {
    session, _ := CreateRkeSession(
        "content.cloudcoin.global",
        "D:/CloudCoin/Wallets/Default",
    )

    if session.Success {
        fmt.Printf("Session ID: %s\n", session.SessionID)
        fmt.Printf("Expires: %s\n", session.ExpiresAt)
    }
}

Related Endpoints

/api/rke/encrypt

Encrypt data using your session.

/api/rke/decrypt

Decrypt data using your session.

/api/rke/session/delete

Delete a session when done.