Skip to main content

Authentication & Security

Learn how to securely authenticate your MCP connections with Unizo APIs and follow security best practices.

API Key Authentication​

Unizo uses API key authentication for all MCP connections. Each request must include a valid API key.

Getting Your API Key​

  1. Log in to the Unizo Console
  2. Navigate to Settings → API Keys
  3. Click "Create New Key"
  4. Name your key (e.g., "MCP Claude Desktop")
  5. Select permissions for the services you'll use
  6. Copy the generated key immediately (it won't be shown again)

API Key Permissions​

Configure specific permissions for enhanced security:

{
"permissions": {
"edr": ["read", "write"],
"ticketing": ["read", "write", "delete"],
"scm": ["read"],
"observability": ["read"]
}
}

Secure Configuration​

Environment Variables​

Recommended: Store credentials in environment variables rather than config files.

# Add to your shell profile (.bashrc, .zshrc, etc.)
export UNIZO_API_KEY="your_api_key_here"
export UNIZO_BASE_URL="https://api.unizo.ai"

Configuration File Security​

If using configuration files, ensure proper file permissions:

# Secure the Claude Desktop config file
chmod 600 ~/Library/Application\ Support/Claude/claude_desktop_config.json

Example Secure Configuration​

{
"mcpServers": {
"unizo-production": {
"command": "npx",
"args": ["@unizo/mcp-server"],
"env": {
"UNIZO_API_KEY": "${UNIZO_API_KEY}",
"UNIZO_BASE_URL": "https://api.unizo.ai",
"UNIZO_ENVIRONMENT": "production"
}
}
}
}

Multiple API Keys​

For different environments or service isolation:

Development vs Production​

{
"mcpServers": {
"unizo-dev": {
"command": "npx",
"args": ["@unizo/mcp-server"],
"env": {
"UNIZO_API_KEY": "${UNIZO_DEV_API_KEY}",
"UNIZO_BASE_URL": "https://dev-api.unizo.ai",
"UNIZO_ENVIRONMENT": "development"
}
},
"unizo-prod": {
"command": "npx",
"args": ["@unizo/mcp-server"],
"env": {
"UNIZO_API_KEY": "${UNIZO_PROD_API_KEY}",
"UNIZO_BASE_URL": "https://api.unizo.ai",
"UNIZO_ENVIRONMENT": "production"
}
}
}
}

Service-Specific Keys​

{
"mcpServers": {
"unizo-security": {
"command": "npx",
"args": ["@unizo/mcp-edr"],
"env": {
"UNIZO_API_KEY": "${UNIZO_SECURITY_KEY}"
}
},
"unizo-devops": {
"command": "npx",
"args": ["@unizo/mcp-scm"],
"env": {
"UNIZO_API_KEY": "${UNIZO_DEVOPS_KEY}"
}
}
}
}

Network Security​

HTTPS Only​

All Unizo API communications use HTTPS. Never configure HTTP endpoints:

{
"env": {
"UNIZO_BASE_URL": "https://api.unizo.ai" // ✅ Secure
// "UNIZO_BASE_URL": "http://api.unizo.ai" // ❌ Insecure
}
}

Proxy Configuration​

For corporate environments with HTTP proxies:

{
"env": {
"UNIZO_API_KEY": "${UNIZO_API_KEY}",
"HTTP_PROXY": "http://proxy.company.com:8080",
"HTTPS_PROXY": "http://proxy.company.com:8080",
"NO_PROXY": "localhost,127.0.0.1"
}
}

Rate Limiting & Quotas​

Understanding Limits​

Each API key has rate limits and quotas:

  • Rate Limit: 100 requests per minute (default)
  • Daily Quota: 10,000 requests per day (default)
  • Concurrent Connections: 5 simultaneous MCP connections

Handling Rate Limits​

MCP servers automatically handle rate limiting with exponential backoff:

{
"env": {
"UNIZO_API_KEY": "${UNIZO_API_KEY}",
"UNIZO_RETRY_ATTEMPTS": "3",
"UNIZO_RETRY_DELAY": "1000",
"UNIZO_MAX_RETRY_DELAY": "10000"
}
}

Security Best Practices​

1. Key Rotation​

Rotate API keys regularly:

# Generate new key
unizo api-keys create --name "MCP-$(date +%Y%m%d)"

# Update configuration
# Revoke old key after confirming new key works
unizo api-keys revoke --key-id old_key_id

2. Least Privilege​

Grant minimum necessary permissions:

{
"permissions": {
"edr": ["read"], // Read-only for monitoring
"ticketing": ["read", "write"], // Read/write for automation
"scm": ["read"] // Read-only for analysis
}
}

3. Environment Isolation​

Use different keys for different environments:

  • Development: Limited permissions, test data only
  • Staging: Production-like permissions, staging data
  • Production: Full permissions, production data

4. Monitoring​

Monitor API key usage:

# Check recent API usage
unizo logs api-usage --key-id your_key_id --since 24h

# Set up alerts for unusual activity
unizo alerts create --condition "api_requests > 1000/hour"

Troubleshooting Authentication​

Common Authentication Errors​

401 Unauthorized

# Check if key is valid
curl -H "Authorization: Bearer your_api_key" https://api.unizo.ai/v1/auth/verify

# Common causes:
# - Invalid or expired API key
# - Key revoked or suspended
# - Incorrect environment (dev key used in prod)

403 Forbidden

# Check key permissions
unizo api-keys describe --key-id your_key_id

# Common causes:
# - Insufficient permissions for the requested resource
# - Service not enabled for your account
# - Rate limit exceeded

Network Errors

# Test connectivity
curl -I https://api.unizo.ai/health

# Check DNS resolution
nslookup api.unizo.ai

# Verify proxy settings if in corporate environment

Debug Authentication​

Enable debug logging:

{
"env": {
"UNIZO_API_KEY": "${UNIZO_API_KEY}",
"UNIZO_LOG_LEVEL": "debug",
"UNIZO_LOG_AUTH": "true"
}
}

Testing Authentication​

Test your setup:

# Test MCP server directly
npx @unizo/mcp-server --test-auth

# Test specific service
npx @unizo/mcp-edr --verify-connection

Advanced Security​

IP Allowlisting​

Restrict API key usage to specific IP addresses:

  1. Go to Unizo Console → API Keys
  2. Select your key
  3. Add allowed IP ranges
  4. Save configuration

Webhook Verification​

For webhook endpoints, verify signatures using the x-unizo-signature and x-unizo-timestamp headers. The signed payload is constructed as {timestamp}.{payload} to prevent replay attacks:

const crypto = require("crypto");

function verifyWebhookSignature(payload, signatureHeader, timestampHeader, secret, toleranceSeconds = 300) {
// Reject stale timestamps to prevent replay attacks
const now = Math.floor(Date.now() / 1000);
const timestamp = parseInt(timestampHeader, 10);
if (Number.isNaN(timestamp) || Math.abs(now - timestamp) > toleranceSeconds) {
return false;
}

// Reconstruct signed payload and compute expected signature
const signedPayload = `${timestamp}.${payload}`;
const expected = crypto.createHmac("sha256", secret).update(signedPayload).digest("hex");

// Strip "v1=" prefix and compare using constant-time function
const received = signatureHeader.startsWith("v1=") ? signatureHeader.slice(3) : signatureHeader;
try {
return crypto.timingSafeEqual(Buffer.from(expected, "hex"), Buffer.from(received, "hex"));
} catch {
return false;
}
}

Need Help?​


Next: Configure your first MCP application or explore service-specific setup guides.