# Security Architecture

The Valu API ecosystem implements multiple layers of security to protect user data, financial transactions, and identity information across all integrated services.

# Mobile App Authentication

# Seed-Based Authentication Flow

sequenceDiagram
    participant User
    participant App as Mobile App
    participant API as Valu API
    participant DB as Database
    
    User->>App: Enter/Generate Seed
    App->>App: Generate Bearer Token from Seed
    Note over App: bearerFromSeed(seed)
    App->>API: POST /sessions/auth/key
    Note over App,API: {secretKey, network}
    API->>DB: Check if secret exists
    alt Secret not found
        API->>DB: Create new user
        DB-->>API: New user & API key
    else Secret exists
        DB-->>API: Existing user & API key
    end
    API-->>App: {authenticatedAs, apiKey, success}
    App->>App: Store credentials & setup interceptors

# Bearer Token Generation

The mobile app generates cryptographically secure bearer tokens from the user's seed:

static bearerFromSeed = async (seed) => {
  var ripemd160 = crypto.createHash("ripemd160");
  var sha256 = crypto.createHash("sha256");

  const VALU_SERVICE_CANONICAL = Buffer.from(VALU_SERVICE_ID, "utf8");

  const sha256Hash = sha256
    .update(await mnemonicToSeed(seed))
    .update(VALU_SERVICE_CANONICAL)
    .digest();

  return ripemd160.update(sha256Hash).digest().toString("hex");
};

Security Features:

  • Uses RIPEMD-160 and SHA-256 hashing
  • Incorporates service-specific canonical identifier
  • Derives from BIP39 mnemonic seed
  • Generates deterministic but unique tokens per service

# Request Signing & Authentication

# API Request Security

flowchart TD
    Request[API Request] --> Method{HTTP Method}
    
    Method -->|GET| GetFlow[Sign URL String]
    Method -->|POST/PUT| PostFlow[Sign URL + JSON Body]
    
    GetFlow --> Sign1[Generate Signature]
    PostFlow --> Sign2[Generate Signature]
    
    Sign1 --> Headers[Add Security Headers]
    Sign2 --> Headers
    
    Headers --> Send[Send Signed Request]
    
    Send --> Verify[Valu API Verifies Signature]
    Verify --> Process[Process Request]

# Request Interceptor Implementation

authenticate(valuToken, apiKey) {
  this.authInterceptor = this.service.interceptors.request.use(
    (config) => {
      config.url = config.url.includes("timestamp")
        ? config.url
        : config.url + `?timestamp=${Date.now()}`;

      if (config.method === "get") {
        config.headers["x-api-signature"] = ValuService.signUrlString(
          axios.getUri(config),
          valuToken
        );
      } else {
        let uri = axios.getUri(config);
        if (uri.substr(0, 4) !== "http") {
          uri = config.baseURL.replace(/\/+$/, "") + uri;
        }
        config.headers["x-api-signature"] = ValuService.signUrlString(
          config.data == null ? uri : uri + JSON.stringify(config.data),
          valuToken
        );
      }
      
      config.headers["x-payload-digest-alg"] = "sha256";
      config.headers["x-api-key"] = apiKey;
      return config;
    }
  );
}

Security Headers:

  • x-api-signature: HMAC signature of request
  • x-payload-digest-alg: Hashing algorithm identifier
  • x-api-key: User-specific API key
  • timestamp: Prevents replay attacks

# External Service Security

# Sumsub KYC Integration

sequenceDiagram
    participant VA as Valu API
    participant SB as Sumsub API
    
    VA->>VA: Generate timestamp
    VA->>VA: Create HMAC signature
    Note over VA: timestamp + method + url + body
    VA->>SB: Request with security headers
    Note over VA,SB: X-App-Token, X-App-Access-Sig, X-App-Access-Ts
    SB->>SB: Verify signature
    SB-->>VA: Authenticated response

Implementation:

const getSigBuilder = (apiToken, secretKey) => config => {
  const timestamp = Math.floor(Date.now() / 1000)
  const signature = crypto.createHmac('sha256', secretKey)

  signature.update(`${timestamp}${_.toUpper(config.method)}${config.url}`)
  if (config.data instanceof FormData) {
    signature.update(config.data.getBuffer())
  } else if (config.data) {
    signature.update(JSON.stringify(config.data))
  }

  config.headers['X-App-Token'] = apiToken
  config.headers['X-App-Access-Sig'] = signature.digest('hex')
  config.headers['X-App-Access-Ts'] = timestamp

  return config
}

# Paybis Payment Security

sequenceDiagram
    participant VA as Valu API
    participant PB as Paybis API
    
    VA->>VA: Hash request body (SHA-512)
    VA->>VA: Sign hash with RSA private key
    Note over VA: RSA-PSS-SALTLEN-DIGEST padding
    VA->>PB: Request with signature header
    Note over VA,PB: X-Request-Signature (Base64)
    PB->>PB: Verify RSA signature
    PB-->>VA: Authenticated response

RSA Signature Implementation:

const getSigBuilder = (privateKey, secretKey) => config => {
  if (!config.data) return config
  
  const hash = crypto.createHash('sha512');
  const hashedData = hash.update(JSON.stringify(config.data), 'utf-8').digest('hex');
  
  const signature = crypto.sign("sha512", Buffer.from(hashedData), {
    key: privateKey,
    padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
    saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST,
  })
  
  config.headers['X-Request-Signature'] = signature.toString('base64')
  return config
}

# Stripe API Security

flowchart LR
    VA[Valu API] -->|Bearer Token| Stripe[Stripe API]
    Stripe -->|HTTPS/TLS| Response[Encrypted Response]
    
    subgraph "Security Layer"
        Bearer[Bearer Token Authentication]
        TLS[TLS 1.3 Encryption]
        Webhook[Webhook Signatures]
    end

Bearer Token Authentication:

const response = await fetch(url, {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${process.env.STRIPE_SK}`,
    'Content-Type': 'application/json'
  }
});

# Blockchain Security

# Verus Blockchain Connection

sequenceDiagram
    participant VA as Valu API
    participant VD as Verus Daemon
    
    VA->>VD: RPC Call with credentials
    Note over VA,VD: HTTP Basic Auth
    VD->>VD: Validate credentials
    VD-->>VA: Blockchain response

Configuration:

// Environment variables for Verus daemon connection
REMOTE_PASS="pass5ed21ad207f6a373d390a"
REMOTE_PROTOCOL="http"
REMOTE_HOST="18.212.94.218"
REMOTE_PORT="18843"
REMOTE_USER="user15"

# Polygon Blockchain Security

flowchart TD
    Wallet[Wallet Instance] --> Provider[JSON RPC Provider]
    Provider --> Network[Polygon Amoy Network]
    
    subgraph "Security Measures"
        PrivKey[Private Key Encryption]
        TxSign[Transaction Signing]
        AddressVal[Address Validation]
    end
    
    Wallet --> PrivKey
    Wallet --> TxSign
    Network --> AddressVal

Secure Transaction Handling:

const provider = new JsonRpcProvider("https://rpc-amoy.polygon.technology/");
const wallet = new Wallet(process.env.POLYGON_AMOY_PRIVATE_KEY, provider);

async function payUSDC(toAddress, amount) {
  try {
    if (!isAddress(toAddress)) {
      throw new Error("Invalid recipient address");
    }
    
    const usdcContract = new Contract(usdcContractAddress, usdcAbi, wallet);
    const amountInSmallestUnit = parseUnits(amount, 6);
    const transactionResponse = await usdcContract.transfer(toAddress, amountInSmallestUnit);
    
    await transactionResponse.wait(); // Wait for confirmation
    return transactionResponse.hash;
  } catch (error) {
    console.error("Error sending USDC payment:", error);
    throw error;
  }
}

# Database Security

# User Data Protection

erDiagram
    USERS {
        uuid id PK
        string status
        string password "Hashed seed"
        uuid api_key
        string network
        timestamp created_at
        timestamp updated_at
    }
    
    SESSIONS {
        uuid session_id PK
        uuid user_id FK
        string bearer_token "Hashed"
        timestamp expires_at
        boolean active
    }
    
    TRANSACTIONS {
        uuid tx_id PK
        uuid user_id FK
        string type
        decimal amount
        string status
        json metadata "Encrypted"
    }

Database Connection Security:

// Environment variables for database
DB_USER='admin'
DB_PASS='encrypted_password'
DB_NAME='valu_db'
DB_HOST="localhost"
DB_PORT="3306"

# Security Best Practices

# 1. Cryptographic Standards

  • SHA-256 and RIPEMD-160 for hashing
  • RSA-PSS for digital signatures
  • HMAC-SHA256 for request authentication
  • TLS 1.3 for transport encryption

# 2. Key Management

flowchart TD
    Seed[User Seed] --> Derive[Key Derivation]
    Derive --> Bearer[Bearer Token]
    Derive --> Wallet[Wallet Keys]
    
    Env[Environment Variables] --> API[API Keys]
    Env --> DB[Database Credentials]
    
    HSM[Hardware Security Module] --> Critical[Critical Keys]
    
    classDef secure fill:#e8f5e8
    class HSM,Critical secure

# 3. Access Control

  • Role-based permissions
  • API rate limiting
  • Session timeout management
  • Multi-factor authentication for admin access

# 4. Audit & Monitoring

  • Request/response logging
  • Failed authentication tracking
  • Anomaly detection
  • Real-time security alerts

# 5. Data Protection

  • Sensitive data encryption at rest
  • PII data anonymization
  • GDPR compliance measures
  • Regular security audits