
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
@scopeblind/verifier
Advanced tools
ScopeBlind protocol verifier SDK for rate limiting and abuse prevention
Official ScopeBlind protocol verifier SDK for Node.js and edge runtimes. Verify blinded tokens, enforce rate limits, and prevent abuse with privacy-preserving cryptography.
npm install @scopeblind/verifier
import { createScopeBlindVerifier } from '@scopeblind/verifier'
const verifier = createScopeBlindVerifier({
secretKey: process.env.SCOPEBLIND_SECRET_KEY!,
issuerPublicKey: process.env.SCOPEBLIND_ISSUER_PUBKEY!,
kvNamespace: yourKVStore, // Optional: for rate limiting and replay protection
rateLimits: {
'comment-submission': { maxRequests: 3, windowSeconds: 86400 },
'signup': { maxRequests: 5, windowSeconds: 86400 },
},
replayWindowSeconds: 3600,
// Optional: Enable telemetry for analytics and auto-tuning
telemetry: {
enabled: true,
tenantId: 'your-project-id',
},
})
const result = await verifier.verify(
payload, // ScopeBlind spend payload from client
{
origin: 'https://example.com',
scope: 'comment-submission',
}
)
if (result.success) {
console.log('✅ Token verified!', result.remaining, 'requests remaining')
// Process the request...
} else {
console.error('❌ Verification failed:', result.error)
// Reject the request
}
| Property | Type | Required | Description |
|---|---|---|---|
secretKey | string | ✅ | Your BRASS API secret key |
issuerPublicKey | string | ✅ | Public key from your ScopeBlind issuer |
issuerUrl | string | ❌ | Issuer endpoint URL (for future features) |
kvNamespace | KVNamespace | ❌ | Key-value store for rate limiting and replay protection |
rateLimits | Record<string, RateLimit> | ❌ | Custom rate limits per scope |
replayWindowSeconds | number | ❌ | How long to track used tokens (default: 3600) |
{
'comment-submission': { maxRequests: 3, windowSeconds: 86400 }, // 3 per day
'signup': { maxRequests: 5, windowSeconds: 86400 }, // 5 per day
'generic': { maxRequests: 10, windowSeconds: 86400 }, // 10 per day
}
import express from 'express'
import { createScopeBlindVerifier } from '@scopeblind/verifier'
const app = express()
const verifier = createScopeBlindVerifier({
secretKey: process.env.SCOPEBLIND_SECRET_KEY!,
issuerPublicKey: process.env.SCOPEBLIND_ISSUER_PUBKEY!,
})
app.post('/api/submit-comment', async (req, res) => {
const brassToken = req.headers['x-brass-token']
// Parse BRASS payload
const payload = JSON.parse(Buffer.from(brassToken, 'base64').toString())
const result = await verifier.verify(payload, {
origin: req.headers.origin,
scope: 'comment-submission',
})
if (!result.success) {
return res.status(429).json({ error: result.error })
}
// Process comment...
res.json({ success: true, remaining: result.remaining })
})
import { createScopeBlindVerifier } from '@scopeblind/verifier'
export default {
async fetch(request: Request, env: Env) {
const verifier = createScopeBlindVerifier({
secretKey: env.SCOPEBLIND_SECRET_KEY,
issuerPublicKey: env.SCOPEBLIND_ISSUER_PUBKEY,
kvNamespace: env.BRASS_KV,
})
const payload = await request.json()
const result = await verifier.verify(payload, {
origin: request.headers.get('origin') || '',
scope: 'comment-submission',
})
if (!result.success) {
return new Response(
JSON.stringify({ error: result.error }),
{ status: 429 }
)
}
return new Response(JSON.stringify({ success: true }))
}
}
import { NextRequest, NextResponse } from 'next/server'
import { createScopeBlindVerifier } from '@scopeblind/verifier'
const verifier = createScopeBlindVerifier({
secretKey: process.env.SCOPEBLIND_SECRET_KEY!,
issuerPublicKey: process.env.SCOPEBLIND_ISSUER_PUBKEY!,
})
export async function POST(request: NextRequest) {
const payload = await request.json()
const result = await verifier.verify(payload.brassToken, {
origin: request.headers.get('origin') || '',
scope: 'comment-submission',
})
if (!result.success) {
return NextResponse.json({ error: result.error }, { status: 429 })
}
return NextResponse.json({ success: true, remaining: result.remaining })
}
While BRASS doesn't use IP addresses for rate limiting or telemetry, you may want to log them locally for your own fraud detection:
const result = await verifier.verify(payload, {
origin: 'https://example.com',
scope: 'comment-submission',
clientIp: req.ip, // Optional: For YOUR local logging only
// IMPORTANT: BRASS telemetry NEVER collects or sends IP addresses
})
// You can log the IP yourself if needed
if (!result.success) {
console.log(`[FRAUD] Failed verification from IP: ${req.ip}`)
}
Privacy Note: The clientIp field is optional context for your own logging. BRASS's privacy-safe telemetry does not collect IP addresses, behavioral profiles, or any personally identifiable information.
Before deploying to production:
BRASS includes opt-in telemetry that powers managed service features like analytics dashboards and auto-calibrated rate limits.
Telemetry is disabled by default for privacy. Enable it to access managed service features:
Option 1: Environment Variables
BRASS_TELEMETRY_ENABLED=true # Must explicitly set to 'true' to enable
BRASS_TELEMETRY_ENDPOINT=https://telemetry.brassproof.com/ingest
BRASS_TENANT_ID=your-project-id
Option 2: Configuration
import { createScopeBlindVerifier } from '@scopeblind/verifier'
const verifier = createScopeBlindVerifier({
secretKey: process.env.SCOPEBLIND_SECRET_KEY!,
telemetry: {
enabled: true,
endpoint: 'https://telemetry.brassproof.com/ingest',
tenantId: 'your-project-id',
onThreshold: (threshold, count) => {
console.log(`Reached ${threshold} verifications! (current: ${count})`)
// Custom logic: send Slack notification, trigger alert, etc.
},
},
})
No action needed - telemetry is off unless you explicitly enable it. If you've enabled it and want to disable:
# Remove or set to false
BRASS_TELEMETRY_ENABLED=false
// Or explicitly disable in code
const verifier = createScopeBlindVerifier({
secretKey: process.env.SCOPEBLIND_SECRET_KEY!,
telemetry: { enabled: false },
})
import { createScopeBlindVerifier } from '@scopeblind/verifier'
const verifier = createScopeBlindVerifier({
secretKey: process.env.SCOPEBLIND_SECRET_KEY!,
telemetry: {
enabled: true,
thresholds: [10000, 50000, 100000], // Custom thresholds
onThreshold: async (threshold, count) => {
// Send to Slack
await fetch(process.env.SLACK_WEBHOOK!, {
method: 'POST',
body: JSON.stringify({
text: `🎉 BRASS milestone: ${count} tokens verified!`,
}),
})
},
},
})
Skip the trial-and-error! Use battle-tested security profiles for common use cases.
| Profile | Use Case | Rate Limit | Token Expiry | Tested With |
|---|---|---|---|---|
comments | Blog comments, forum posts, reviews | 3 req/day | 5min | 500k+ submissions |
signup | User registration, trial signups | 5 req/hour | 10min | 2M+ signups |
api | REST APIs, GraphQL, webhooks | 60 req/min | 2min | 50M+ API calls |
ecommerce | Checkout, payments, cart operations | 10 req/hour | 30min | 10M+ transactions |
import { createScopeBlindVerifier } from '@scopeblind/verifier'
// Instantly configure for your use case
const verifier = createScopeBlindVerifier({
secretKey: process.env.SCOPEBLIND_SECRET_KEY!,
calibrationProfile: 'ecommerce', // Pre-tuned for checkout flows
})
Output:
[BRASS] Applied calibration profile: "ecommerce" (1.0)
Description: Checkout flows and high-value transactions
Rate Limit: 10 requests per 3600s
Token Expiry: 1800s
Certification: brass-verified
const verifier = createScopeBlindVerifier({
secretKey: process.env.SCOPEBLIND_SECRET_KEY!,
calibrationProfile: 'comments',
profileOverrides: {
rateLimit: { maxRequests: 5 }, // Allow 5 comments/day instead of 3
tokens: { maxAgeSeconds: 600 } // Extend token lifetime to 10min
}
})
import { listProfiles } from '@scopeblind/verifier'
const profiles = listProfiles()
profiles.forEach(p => {
console.log(`${p.name}: ${p.description}`)
console.log(` Tested with: ${p.metadata.testedWith}`)
console.log(` Warnings: ${p.metadata.warnings?.join(', ')}`)
})
import { recommendProfile } from '@scopeblind/verifier'
const profile = recommendProfile('user comments on blog posts')
// Returns: 'comments'
const verifier = createScopeBlindVerifier({
secretKey: process.env.SCOPEBLIND_SECRET_KEY!,
calibrationProfile: profile,
})
Available to managed customers via private beta invitation:
These advanced features build on the core calibration profiles available to all users today. See the main README feature table for current availability.
Contact sales@brassproof.com for private beta access.
Get notified when critical events occur. Perfect for DDoS detection, rate limit monitoring, and security incident response.
import { createScopeBlindVerifier } from '@scopeblind/verifier'
const verifier = createScopeBlindVerifier({
secretKey: process.env.SCOPEBLIND_SECRET_KEY!,
telemetry: {
enabled: true,
alerts: {
webhooks: [{
url: 'https://your-alerting-service.com/hook',
secret: process.env.WEBHOOK_SECRET // For HMAC signature verification
}],
severities: ['critical'], // Only send critical alerts (DDoS, massive abuse)
maxAlertsPerDay: 5, // Prevent alert spam
dryRun: true // Test config without sending (RECOMMENDED for testing)
}
}
})
| Severity | When to Use | Examples |
|---|---|---|
critical | Infrastructure threats, massive abuse | DDoS attack, 10x traffic spike, complete service outage |
warning | Elevated activity, potential issues | 2-5x traffic increase, sustained high rate limit hits |
info | Milestone events, normal operations | Threshold reached (50k tokens), new deployment |
Default: critical only (prevents alert fatigue)
Alerts are sent as POST requests with HMAC SHA-256 signatures:
{
"alert": {
"severity": "critical",
"title": "DDoS Attack Detected",
"message": "Traffic spike: 10x normal rate detected on /api/submit",
"timestamp": 1699123456789,
"metadata": {
"scope": "api",
"currentRate": 1000,
"normalRate": 100
}
},
"tenantId": "your-project-id",
"timestamp": 1699123456789
}
Headers:
Content-Type: application/json
X-BRASS-Event: alert
X-Brass-Signature: sha256=<hmac_sha256_hex>
import crypto from 'crypto'
function verifyWebhook(req: Request, secret: string): boolean {
const signature = req.headers['x-brass-signature']
const payload = JSON.stringify(req.body)
const hmac = crypto.createHmac('sha256', secret)
hmac.update(payload)
const expected = `sha256=${hmac.digest('hex')}`
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
)
}
const verifier = createScopeBlindVerifier({
secretKey: process.env.SCOPEBLIND_SECRET_KEY!,
telemetry: {
enabled: true,
alerts: {
slack: {
webhookUrl: process.env.SLACK_WEBHOOK_URL!
},
severities: ['critical', 'warning'],
maxAlertsPerDay: 10
}
}
})
Alerts include built-in protections against spam:
const verifier = createScopeBlindVerifier({
secretKey: process.env.SCOPEBLIND_SECRET_KEY!,
telemetry: {
enabled: true,
alerts: {
webhooks: [{ url: '...' }],
maxAlertsPerDay: 10, // Raise limit for high-volume apps
debounceMinutes: 30, // Reduce debounce for faster alerts
dryRun: true, // Test mode: logs alerts without sending
severities: ['critical'] // Only the most important events
}
}
})
import { Telemetrist } from '@scopeblind/verifier'
const telemetrist = new Telemetrist({
enabled: true,
alerts: {
webhooks: [{ url: '...' }],
severities: ['critical'],
dryRun: false
}
})
// Trigger custom alert
await telemetrist.emitAlert({
severity: 'critical',
title: 'Database Connection Lost',
message: 'Primary database unreachable for 30 seconds',
timestamp: Date.now(),
metadata: { database: 'postgres-primary', downtime: 30 }
})
Available to managed customers via invitation-only beta:
Core webhook support (shown above) is available to all users today. See the main README feature table for current availability.
Contact sales@brassproof.com for private beta access.
Show your users you're using privacy-first abuse prevention with an embeddable badge (similar to reCAPTCHA).
Note: Badge is exported separately to avoid forcing React as a dependency for server-side users.
import { BrassBadge } from '@scopeblind/verifier/badge'
function App() {
return (
<div>
<h1>Your App</h1>
{/* Badge appears in bottom-right by default */}
<BrassBadge />
</div>
)
}
<BrassBadge
position="bottom-left"
variant="compact"
theme="dark"
linkUrl="https://brassproof.com"
/>
{/* Disable badge */}
<BrassBadge enabled={false} />
<script src="https://cdn.brassproof.com/badge.js"></script>
<script>
BRASSBadge.init({
position: 'bottom-right',
variant: 'default',
theme: 'auto', // Follows system dark mode preference
})
</script>
<!-- Disable badge -->
<script>
BRASSBadge.init({ enabled: false })
</script>
| Property | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Show/hide badge |
position | 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'bottom-right' | Badge position |
variant | 'default' | 'minimal' | 'compact' | 'default' | Badge size/style |
theme | 'light' | 'dark' | 'auto' | 'auto' | Color scheme |
linkUrl | string | 'https://brassproof.com' | Where badge links to |
# Required
SCOPEBLIND_SECRET_KEY=your_secret_key_here
SCOPEBLIND_ISSUER_PUBKEY=issuer_public_key_hex
# Optional - Telemetry
BRASS_TELEMETRY_ENABLED=true
BRASS_TELEMETRY_ENDPOINT=https://telemetry.brassproof.com/ingest
BRASS_TENANT_ID=your-project-id
# Optional - Verifier
BRASS_ISSUER_URL=https://brass-issuer.your-domain.workers.dev
createScopeBlindVerifier(config: ScopeBlindVerifierConfig): BrassVerifierCreates a new BRASS verifier instance.
verifier.verify(payload: BrassSpendPayload, context: VerificationContext): Promise<VerificationResult>Verifies a BRASS token and enforces rate limits.
Parameters:
payload: The ScopeBlind spend payload from the clientcontext: Verification context including origin and scopeReturns:
{
success: boolean
error?: string // Error message if verification failed
remaining?: number // Remaining requests in current window
resetAt?: number // Timestamp when rate limit resets
metadata?: object // Additional verification metadata
}
See docs/verifier.md for complete self-hosting instructions including:
MIT - see LICENSE for details.
FAQs
ScopeBlind protocol verifier SDK for rate limiting and abuse prevention
We found that @scopeblind/verifier demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.