Configuring Policies

Create and manage cryptographic policies that define relationships between services

Policies are the edges in your 4Quays graph. Each policy defines the cryptographic relationship between a source service and a destination service.

What Policies Define

A policy specifies:

  • Source service: The application making the request
  • Destination service: The external system receiving the payload
  • Algorithm: How to protect the payload
  • Keys: Which keys to use
  • Direction: Protect, unprotect, or both
  • Failure mode: What happens when the policy is inactive

Policy Numbers

Every policy has a policy number — the identifier your application can use when calling /protect or /unprotect:

// Explicitly specify a policy
const response = await fetch(endpoint + '/api/v1/protect', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    payload,
    policyNumber: 'BANK-A-TRANSFER-001',
  }),
});

If policyNumber is omitted, the API uses the policy bound to the authenticated API key. This is the recommended approach when each API key is scoped to a single policy.

Policy numbers should be:

  • Descriptive and consistent
  • Include version or environment indicators
  • Easy to reference in code

Examples:

  • RBC-TRANSFER-PROD-001
  • SCOTIA-PAYMENT-V2
  • CRA-TAX-FILING-2026

Creating Policies

Via Dashboard

  1. Navigate to Policies in the sidebar
  2. Click Create Policy
  3. Configure the policy:
    • Policy Number: Unique identifier
    • Source Service: Your application
    • Destination Service: External system
    • Algorithm: Encryption configuration
    • Description: What this policy is for
  4. Click Create

Via Enrollment Wizard

The enrollment wizard creates policies automatically as part of the guided setup flow. This is the recommended approach for new integrations.

Algorithm Configuration

Encryption Policies

For confidentiality (encrypting data):

Supported configurations:

  • AES-256-GCM + RSA-2048
  • AES-256-GCM + RSA-4096
  • AES-256-GCM + ML-KEM-768 (post-quantum)
  • AES-256-GCM + ML-KEM-1024 (post-quantum)

Failure Modes

When a policy is inactive, the failure_mode setting determines what happens:

Failure ModeBehavior
errorReturns a POLICY_NOT_ACTIVE error (403). This is the default.
passthroughReturns the payload unencrypted with a warning. Useful for development and testing.
dropAccepts the request but discards the payload. Returns a success response with dropped: true.

Policy Status

StatusDescription
ActivePolicy is available for use
InactivePolicy is disabled; behavior depends on failure mode

Viewing Policy Details

The policy detail page shows:

  • Configuration details
  • Associated keys
  • Usage statistics
  • Error rates

Policy Graph

Visualize your policy relationships:

               ┌─────────────────┐
               │  Banking App    │
               │    (source)     │
               └────────┬────────┘
                        │
         ┌──────────────┼──────────────┐
         │              │              │
         ▼              ▼              ▼
┌─────────────┐  ┌─────────────┐  ┌─────────────┐
│    RBC      │  │ Scotiabank  │  │     BMO     │
│  (AES+RSA)  │  │ (AES+MLKEM) │  │  (AES+RSA)  │
└─────────────┘  └─────────────┘  └─────────────┘

Best Practices

Naming

Use structured policy numbers:

Format: {DESTINATION}-{OPERATION}-{ENVIRONMENT}-{VERSION}

Examples:
- RBC-TRANSFER-PROD-001
- RBC-TRANSFER-STAGE-001
- RBC-STATEMENT-PROD-001

Documentation

Include detailed descriptions:

Good: "Production transfers to RBC. Uses AES-256-GCM with RSA-2048 key
      wrapping per RBC's 2026 specification. Key imported from RBC on
      2026-01-10."

Poor: "RBC transfers"

Separation

Create separate policies for:

  • Different environments (dev, staging, prod)
  • Different operations (transfers, statements)
  • Different data sensitivity levels

What's Next