Development vs Production
Understand passthrough mode for development and production mode with 4Quays
The 4Quays SDK operates in two modes, determined entirely by configuration. This makes local development simple while ensuring production security.
The Two Modes
Passthrough Mode (Development)
When no 4Quays endpoint is configured, the SDK operates in passthrough mode:
protect()returns the payload unchangedunprotect()returns the payload unchanged- No network calls to 4Quays
- No API key required
// No endpoint configured = passthrough mode
const fourq = new FourQ({
endpoint: undefined, // or omit entirely
apiKey: undefined,
});
const payload = { amount: 1000 };
const result = await fourq.protect(payload, 'ANY-POLICY');
console.log(result === payload); // true (in passthrough mode)
Production Mode
When a 4Quays endpoint is configured, the SDK routes operations through the platform:
protect()calls 4Quays API and returns encrypted payloadunprotect()calls 4Quays API and returns decrypted payload- Requires valid API key
- All operations are audited
// Endpoint configured = production mode
const fourq = new FourQ({
endpoint: 'https://api.4quays.com',
apiKey: 'sk_live_xxxxx',
});
const payload = { amount: 1000 };
const result = await fourq.protect(payload, 'BANK-POLICY');
console.log(result === payload); // false (encrypted)
Why Passthrough Mode?
Passthrough mode enables:
- Local development without infrastructure — No 4Quays platform needed during development
- Write once, run anywhere — Same code works in dev and prod
- Test business logic first — Focus on application logic, add crypto later
- Team independence — Developers don't need security team for local work
Configuration Patterns
Environment-Based Switching
Use environment variables to switch modes:
# .env.development # FOURQ_ENDPOINT= (not set = passthrough) # FOURQ_API_KEY= (not set = passthrough) # .env.production FOURQ_ENDPOINT=https://api.4quays.com FOURQ_API_KEY=sk_live_xxxxx
const fourq = new FourQ({
endpoint: process.env.FOURQ_ENDPOINT,
apiKey: process.env.FOURQ_API_KEY,
});
Explicit Mode Checking
Check which mode is active:
const health = await fourq.checkHealth();
if (health.mode === 'passthrough') {
console.log('Running in development mode');
} else {
console.log('Connected to 4Quays:', health.latencyMs, 'ms');
}
Development Workflow
Step 1: Write Code with SDK
During development, write your integration using the SDK:
async function processTransfer(transferData) {
// Protect payload (passthrough in dev)
const protected = await fourq.protect(
transferData,
'BANK-TRANSFER-POLICY'
);
// Send to bank API
const response = await bankApi.submitTransfer(protected);
return response;
}
Step 2: Test Without 4Quays
Run your tests without any 4Quays infrastructure:
test('transfer processing', async () => {
const result = await processTransfer({
amount: 1000,
destination: 'CA1234567890'
});
expect(result.status).toBe('accepted');
});
In passthrough mode, the bank API receives plaintext — this may result in rejections from services that require encryption. That's expected during development.
Step 3: Deploy to Staging
Configure staging environment with 4Quays:
# staging.env FOURQ_ENDPOINT=https://staging-api.4quays.com FOURQ_API_KEY=sk_test_xxxxx
Now the same code protects payloads properly.
Step 4: Deploy to Production
Configure production environment:
# production.env FOURQ_ENDPOINT=https://api.4quays.com FOURQ_API_KEY=sk_live_xxxxx
Zero code changes between environments.
Testing Considerations
Unit Tests
For unit tests, passthrough mode is usually sufficient:
// fourq.mock.js
export const fourq = new FourQ({
endpoint: undefined, // passthrough
});
Integration Tests
For integration tests against external services, you may need a test 4Quays environment:
// fourq.test.js
export const fourq = new FourQ({
endpoint: process.env.FOURQ_TEST_ENDPOINT,
apiKey: process.env.FOURQ_TEST_API_KEY,
});
Mocking 4Quays
You can also mock the SDK entirely:
jest.mock('@4quays/sdk', () => ({
FourQ: jest.fn().mockImplementation(() => ({
protect: jest.fn().mockResolvedValue({ encrypted: true }),
unprotect: jest.fn().mockResolvedValue({ decrypted: true }),
checkHealth: jest.fn().mockResolvedValue({ mode: 'mock' }),
})),
}));
Debugging Mode Behavior
When debugging, log the current mode:
const fourq = new FourQ({
endpoint: process.env.FOURQ_ENDPOINT,
apiKey: process.env.FOURQ_API_KEY,
});
const health = await fourq.checkHealth();
console.log(`4Quays mode: ${health.mode}`);
console.log(`Latency: ${health.latencyMs}ms`);
Common Patterns
Conditional Logging
const result = await fourq.protect(payload, 'POLICY');
if (process.env.NODE_ENV === 'development') {
// Safe to log in dev (passthrough = plaintext)
console.log('Payload:', result);
} else {
// Don't log encrypted content in prod
console.log('Payload protected');
}
Fallback Behavior
async function protectWithFallback(payload, policy) {
try {
return await fourq.protect(payload, policy);
} catch (error) {
if (process.env.NODE_ENV === 'development') {
console.warn('4Quays unavailable, using passthrough');
return payload;
}
throw error;
}
}
What's Next
- Example Walkthrough — Complete integration example
- API Reference — Detailed API documentation