Abbox Guard Documentation

Complete guide to integrating Abbox Guard into your SaaS application. Protect your AI prompts with policy-based validation in minutes.

Table of Contents

Quick StartAPI ReferenceIntegration PatternsLanguage ExamplesBest PracticesTroubleshooting

Overview

Abbox Guard evaluates user prompts against your company's security policies before they reach your AI models. It returns a decision (allow or block) along with a reason and optional suggested rewrite.

Quick Start

1. Get Your API Key

  1. Sign up at app.abbox.com
  2. Create a company
  3. Generate an API key from the dashboard
  4. Copy your API key (format: abbox_live_{keyId}_{secret})

2. Set Environment Variables

Add these to your .env file:

ABBOX_API_KEY=abbox_live_your_key_id_your_secret
ABBOX_API_BASE_URL=https://api.abbox.com  # or your self-hosted URL

3. Install the SDK (Recommended)

Install the official npm package:

npm install @abbox/guard

4. Basic Integration

Check the prompt before processing. Use ABBOX_API_KEY and ABBOX_API_BASE_URL (e.g. http://localhost:4000) in your environment:

1. Import

import { checkWithAbboxGuard, shouldBlock, hasSuggestedRewrite } from '@abbox/guard';

2. Integration code

// Abbox Guard: Check prompt before processing
try {
  const decision = await checkWithAbboxGuard(
    {
      prompt: parsed.data.prompt,
      source: "abbox-saas-server",
      actorId: "system",
    },
    {
      apiKey: process.env.ABBOX_API_KEY,
      baseUrl: process.env.ABBOX_API_BASE_URL || "http://localhost:4000",
    },
  );
  // Block if decision is "block" or has suggested rewrite
  if (shouldBlock(decision) || hasSuggestedRewrite(decision)) {
    return res.json({
      abboxGuard: {
        decision: decision.decision,
        reason: decision.reason,
        suggestedRewrite: decision.suggested_rewrite,
      },
      message:
        decision.decision === "block"
          ? "Request blocked by abbox guard policy."
          : "Request requires modification. See suggested_rewrite.",
      data: [],
      rowCount: 0,
    });
  }
  // If allowed, continue with normal flow
} catch (e: any) {
  console.error("[ask-route] Abbox Guard error:", e);
  return res.status(500).json({
    error: "abbox_guard_error",
    message: `Failed to check prompt: ${String(e?.message ?? e)}`,
  });
}

Or use the raw API (no dependencies):

async function checkWithAbboxGuard(prompt, source, actorId) {
  const res = await fetch(`${process.env.ABBOX_API_BASE_URL || 'https://api.abbox.com'}/v1/decide`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${process.env.ABBOX_API_KEY}`
    },
    body: JSON.stringify({
      prompt,
      source,
      actor: { id: actorId },
      metadata: {}
    })
  });
  if (!res.ok) throw new Error(`Abbox Guard error: ${res.statusText}`);
  return await res.json();
}

API Reference

Endpoint

POST /v1/decide

Request

Headers:

  • Authorization: Bearer {ABBOX_API_KEY}
  • Content-Type: application/json

Body:

{
  "prompt": "string (required) - The user's prompt to evaluate",
  "source": "string (required) - Your application identifier",
  "actor": {
    "id": "string (required) - User/session identifier"
  },
  "metadata": {
    "key": "value (optional) - Additional context"
  }
}

Response

Success (200):

{
  "decision": "allow" | "block",
  "reason": "Brief explanation of the decision",
  "intent": {
    "type": "query.personal_info",
    ...
  },
  "policy": {
    "id": "policy-uuid",
    "version": 1
  } | null,
  "suggested_rewrite": "Alternative prompt" | null
}

Error (401):

{
  "error": "Invalid or missing API key"
}

Error (400):

{
  "error": "Invalid payload"
}

Integration Patterns

Pattern 1: Block and Return Error

const decision = await checkWithAbboxGuard({
  prompt,
  source: 'my-app',
  actorId: userId
});

if (decision.decision === 'block') {
  throw new Error(`Request blocked: ${decision.reason}`);
}

// Continue with AI processing

Pattern 2: Suggest Rewrite to User

const decision = await checkWithAbboxGuard({
  prompt,
  source: 'my-app',
  actorId: userId
});

if (decision.suggested_rewrite) {
  return {
    error: 'Please rephrase your request',
    suggestion: decision.suggested_rewrite,
    reason: decision.reason
  };
}

// Continue with AI processing

Pattern 3: Auto-Apply Rewrite

let finalPrompt = prompt;
const decision = await checkWithAbboxGuard({
  prompt,
  source: 'my-app',
  actorId: userId
});

if (decision.decision === 'block') {
  throw new Error(`Request blocked: ${decision.reason}`);
}

if (decision.suggested_rewrite) {
  finalPrompt = decision.suggested_rewrite;
  // Optionally log that a rewrite was applied
}

// Continue with AI processing using finalPrompt

Pattern 4: Fail-Open (Allow on Error)

import { checkWithAbboxGuardFailOpen } from '@abbox/guard';

try {
  const decision = await checkWithAbboxGuardFailOpen({
    prompt,
    source: 'my-app',
    actorId: userId
  });
  if (decision.decision === 'block') {
    throw new Error(`Blocked: ${decision.reason}`);
  }
} catch (error) {
  // If Abbox Guard is unavailable, allow the request
  console.warn('Abbox Guard unavailable, allowing request:', error);
}

// Continue with AI processing

Pattern 5: Fail-Closed (Block on Error)

import { checkWithAbboxGuardFailClosed } from '@abbox/guard';

try {
  const decision = await checkWithAbboxGuardFailClosed({
    prompt,
    source: 'my-app',
    actorId: userId
  });
  if (decision.decision === 'block') {
    throw new Error(`Blocked: ${decision.reason}`);
  }
} catch (error) {
  // If Abbox Guard is unavailable, block the request for security
  throw new Error('Policy check unavailable - request blocked for security');
}

Language Examples

Node.js / Express

const express = require('express');
const app = express();

async function checkPromptWithAbbox(prompt, source, actorId) {
  const response = await fetch(`${process.env.ABBOX_API_BASE_URL}/v1/decide`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${process.env.ABBOX_API_KEY}`
    },
    body: JSON.stringify({
      prompt,
      source,
      actor: { id: actorId },
      metadata: {}
    })
  });
  return await response.json();
}

app.post('/api/chat', async (req, res) => {
  const { prompt, userId } = req.body;
  
  const decision = await checkPromptWithAbbox(prompt, 'my-app', userId);
  
  if (decision.decision === 'block') {
    return res.status(403).json({ error: decision.reason });
  }
  
  // Continue with AI processing...
});

Python / FastAPI

import os
import httpx

async def check_prompt_with_abbox(prompt: str, source: str, actor_id: str):
    api_key = os.getenv('ABBOX_API_KEY')
    base_url = os.getenv('ABBOX_API_BASE_URL', 'https://api.abbox.com')
    
    async with httpx.AsyncClient() as client:
        response = await client.post(
            f"{base_url}/v1/decide",
            headers={
                'Authorization': f'Bearer {api_key}',
                'Content-Type': 'application/json'
            },
            json={
                'prompt': prompt,
                'source': source,
                'actor': {'id': actor_id},
                'metadata': {}
            }
        )
        return response.json()

@app.post('/api/chat')
async def chat(request: ChatRequest):
    decision = await check_prompt_with_abbox(
        request.prompt, 'my-app', request.user_id
    )
    
    if decision['decision'] == 'block':
        raise HTTPException(status_code=403, detail=decision['reason'])
    
    # Continue with AI processing...

Go

package main

import (
    "bytes"
    "encoding/json"
    "net/http"
    "os"
)

type Decision struct {
    Decision        string `json:"decision"`
    Reason          string `json:"reason"`
    SuggestedRewrite string `json:"suggested_rewrite"`
}

func checkPromptWithAbbox(prompt, source, actorID string) (*Decision, error) {
    apiKey := os.Getenv("ABBOX_API_KEY")
    baseURL := os.Getenv("ABBOX_API_BASE_URL")
    if baseURL == "" {
        baseURL = "https://api.abbox.com"
    }
    
    body, _ := json.Marshal(map[string]interface{}{
        "prompt": prompt,
        "source": source,
        "actor": map[string]string{"id": actorID},
        "metadata": map[string]interface{}{},
    })
    
    req, _ := http.NewRequest("POST", baseURL+"/v1/decide", bytes.NewBuffer(body))
    req.Header.Set("Authorization", "Bearer "+apiKey)
    req.Header.Set("Content-Type", "application/json")
    
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    
    var decision Decision
    json.NewDecoder(resp.Body).Decode(&decision)
    return &decision, nil
}

Best Practices

  1. Always validate prompts before AI processing - Check prompts early in your request flow
  2. Handle errors gracefully - Decide on fail-open vs fail-closed based on your security needs
  3. Log decisions - Abbox automatically logs all decisions, but you may want to log in your system too
  4. Use meaningful source identifiers - Use consistent source names for better analytics
  5. Include actor IDs - Track which users are making requests
  6. Respect suggested rewrites - When provided, they help users comply with policies

Security Considerations

  • API Key Security: Never expose your API key in client-side code
  • Fail-Closed vs Fail-Open: For high-security applications, consider blocking requests when Abbox Guard is unavailable
  • Rate Limiting: Implement rate limiting on your side to prevent abuse
  • Timeout Handling: Set reasonable timeouts (e.g., 5 seconds) for Abbox Guard calls

Troubleshooting

"Invalid or missing API key"

  • Verify ABBOX_API_KEY is set correctly
  • Ensure the key format is abbox_live_{keyId}_{secret}
  • Check for extra spaces or newlines in the environment variable

"Policy check unavailable"

  • Check network connectivity to ABBOX_API_BASE_URL
  • Verify the API endpoint is accessible
  • Check API status at your dashboard

Timeout errors

  • Increase timeout for Abbox Guard calls
  • Consider implementing retry logic with exponential backoff
  • Use fail-open pattern if timeouts are frequent

Support

Need help? We're here for you: