> ## Documentation Index
> Fetch the complete documentation index at: https://docs.layerzero.network/llms.txt
> Use this file to discover all available pages before exploring further.

# Gasolina Implementation Guide

> Step-by-step instructions for deploying Gasolina on AWS or Google Cloud Platform, including configuration, signer setup, and integration with LayerZero.

This guide provides step-by-step instructions for deploying your own Gasolina instance on AWS or Google Cloud Platform. Gasolina is a REST API service that verifies LayerZero messages and produces signatures for DVN contracts.

## Prerequisites

Before deploying Gasolina, ensure you have:

| Requirement                | Details                                                                |
| -------------------------- | ---------------------------------------------------------------------- |
| **Cloud Provider Account** | AWS account with CDK permissions, or GCP account with billing enabled  |
| **Node.js**                | Version 18 or higher                                                   |
| **Package Manager**        | npm, yarn, or pnpm                                                     |
| **Cloud CLI**              | AWS CLI + CDK CLI, or gcloud CLI + Terraform                           |
| **RPC Providers**          | Reliable endpoints for each supported chain (2+ per chain recommended) |

***

## AWS Implementation

### Step 1: Clone and Setup

```bash wrap theme={null}
# Clone the repository
git clone https://github.com/LayerZero-Labs/gasolina-aws.git
cd gasolina-aws

# Install dependencies
pnpm install
# or: yarn install
```

### Step 2: Configure AWS Authentication

```bash wrap theme={null}
# Configure AWS CLI with your credentials
aws configure

# Verify authentication
aws sts get-caller-identity
```

### Step 3: Choose Signer Type

You have two options for managing signing keys:

<Tabs>
  <Tab title="AWS KMS (Recommended)">
    AWS KMS provides HSM-backed signing keys that are automatically created and managed:

    1. Set `signerType: 'KMS'` in your configuration
    2. Specify `kmsNumOfSigners` for the number of keys to create
    3. Keys are automatically created during CDK deployment

    **Benefits:**

    * Hardware security module protection
    * Automatic key rotation support
    * No manual secret management
  </Tab>

  <Tab title="Mnemonic-based">
    For mnemonic-based signers, create secrets in AWS Secrets Manager:

    ```bash wrap theme={null}
    # Create a secret for each signer
    aws secretsmanager create-secret \
        --name "gasolina-signer-1" \
        --secret-string '{
            "LAYERZERO_WALLET_MNEMONIC": "your twelve word mnemonic phrase here",
            "LAYERZERO_WALLET_PATH": "m/44'"'"'/60'"'"'/0'"'"'/0/0"
        }'
    ```

    <Warning>
      Store mnemonics securely and never commit them to version control. Use AWS Secrets Manager or similar secure storage.
    </Warning>
  </Tab>
</Tabs>

### Step 4: Configure Infrastructure

Edit `cdk/gasolina/config/index.ts`:

```typescript wrap theme={null}
export const CONFIG = {
  '123456789012': {
    // Your AWS account number
    projectName: 'my-gasolina-mainnet', // Must be globally unique
    environment: 'mainnet', // or "testnet"
    availableChainNames: 'ethereum,bsc,avalanche,polygon,arbitrum,optimism',
    signerType: 'KMS', // or "MNEMONIC"
    kmsNumOfSigners: 3, // Only if using KMS
    // Optional: Extra context verification
    extraContextGasolinaUrl: 'https://your-verification-api.com/verify',
  },
};
```

| Config Option             | Description                                           |
| ------------------------- | ----------------------------------------------------- |
| `projectName`             | Unique project identifier (used for S3 bucket naming) |
| `environment`             | `mainnet` or `testnet`                                |
| `availableChainNames`     | Comma-separated list of supported chains              |
| `signerType`              | `KMS` for HSM-backed or `MNEMONIC` for secret-based   |
| `kmsNumOfSigners`         | Number of KMS signing keys to create                  |
| `extraContextGasolinaUrl` | Optional custom verification endpoint                 |

### Step 5: Configure RPC Providers

Edit `cdk/gasolina/config/providers/mainnet/providers.json`:

```json wrap theme={null}
{
  "1": {
    "chainName": "ethereum",
    "uris": [
      "https://eth-mainnet.g.alchemy.com/v2/YOUR-API-KEY",
      "https://mainnet.infura.io/v3/YOUR-PROJECT-ID"
    ]
  },
  "56": {
    "chainName": "bsc",
    "uris": ["https://bsc-dataseed1.binance.org", "https://bsc-dataseed2.ninicoin.io"]
  }
}
```

<Tip>
  * Use at least 2 RPC providers per chain for redundancy
  * Prioritize reliable providers (Alchemy, Infura, QuickNode)
  * Order URIs by preference (first URI is primary)
</Tip>

### Step 6: Configure Wallet Definitions (Mnemonic Only)

If using mnemonics, edit `cdk/gasolina/config/walletConfig/mainnet.json`:

```json wrap theme={null}
{
  "definitions": [
    {
      "address": "0x1234567890123456789012345678901234567890",
      "secretName": "gasolina-signer-1"
    },
    {
      "address": "0x0987654321098765432109876543210987654321",
      "secretName": "gasolina-signer-2"
    }
  ]
}
```

### Step 7: Bootstrap CDK (First Time Only)

```bash wrap theme={null}
cd cdk/gasolina
cdk bootstrap
```

### Step 8: Deploy Infrastructure

```bash wrap theme={null}
# Review the deployment plan
cdk diff

# Deploy the infrastructure
cdk deploy
```

After successful deployment, you'll see:

```
Outputs:
Oracle.ApiGatewayUrl = https://xxxxxxxxxx.execute-api.region.amazonaws.com
```

### Step 9: Test Deployment

```bash wrap theme={null}
# Test the health endpoint
curl https://xxxxxxxxxx.execute-api.region.amazonaws.com

# Test signer info
curl "https://xxxxxxxxxx.execute-api.region.amazonaws.com/signer-info?chainName=ethereum"

# Run comprehensive test
cd ../../  # Back to repository root
ts-node scripts/testDeployment.ts -u https://xxxxxxxxxx.execute-api.region.amazonaws.com -e mainnet
```

A successful response looks like:

```
--- [200] Successful request ---
Response: {
  signatures: [
    { signature: '<signature>', address: '<address>' },
    { signature: '<signature>', address: '<address>' }
  ]
}
```

***

## Google Cloud Platform Implementation

### Step 1: Clone and Setup

```bash wrap theme={null}
# Clone the repository
git clone https://github.com/LayerZero-Labs/gasolina-gcp.git
cd gasolina-gcp

# Install dependencies
yarn install
```

### Step 2: Configure GCP Project

```bash wrap theme={null}
# Set your project
gcloud config set project YOUR-PROJECT-ID

# Authenticate
gcloud auth application-default login

# Enable required APIs
gcloud services enable cloudkms.googleapis.com
gcloud services enable run.googleapis.com
gcloud services enable secretmanager.googleapis.com
```

### Step 3: Create Terraform Backend Storage

```bash wrap theme={null}
# Create a GCS bucket for Terraform state
gsutil mb -p YOUR-PROJECT-ID -l US-EAST1 gs://your-project-gasolina-tfstate
```

### Step 4: Configure Terraform Backend

Edit `terraform/lz-mainnet-verifier.backend.conf`:

```hcl wrap theme={null}
bucket = "your-project-gasolina-tfstate"
prefix = "mainnet"
```

### Step 5: Configure Infrastructure Variables

Edit `terraform/lz-mainnet-verifier.tfvars`:

```hcl wrap theme={null}
/* Project variables */
project    = "your-gcp-project"
project_id = "123456789012"
region     = "us-east1"
zone       = "us-east1-c"

/* General variables */
env = "mainnet"

/* KMS-HSM variables */
num_signers = 3

/* App variables */
app_name = "gasolina-api"
available_chain_names = "ethereum,bsc,avalanche,polygon,arbitrum,optimism"
```

### Step 6: Configure RPC Providers

Edit `terraform/providers-mainnet.json`:

```json wrap theme={null}
{
  "1": {
    "chainName": "ethereum",
    "uris": [
      "https://eth-mainnet.g.alchemy.com/v2/YOUR-API-KEY",
      "https://mainnet.infura.io/v3/YOUR-PROJECT-ID"
    ]
  },
  "56": {
    "chainName": "bsc",
    "uris": ["https://bsc-dataseed1.binance.org", "https://bsc-dataseed2.ninicoin.io"]
  }
}
```

### Step 7: Deploy with Terraform

```bash wrap theme={null}
cd terraform

# Initialize Terraform
terraform init -backend-config=lz-mainnet-verifier.backend.conf -reconfigure

# Review the deployment plan
terraform plan --var-file=lz-mainnet-verifier.tfvars

# Apply the deployment
terraform apply --var-file=lz-mainnet-verifier.tfvars
```

### Step 8: Test Deployment

```bash wrap theme={null}
# Get the Cloud Run URL
GASOLINA_URL=$(gcloud run services describe gasolina-api \
    --region=us-east1 \
    --format='value(status.url)')

# Test health endpoint
curl $GASOLINA_URL

# Test signer info
curl "$GASOLINA_URL/signer-info?chainName=ethereum"

# Run comprehensive test
cd ..  # Back to repository root
ts-node scripts/testDeployment.ts -u $GASOLINA_URL -e mainnet
```

***

## Integration with LayerZero

Once your Gasolina instance is deployed and tested:

### Step 1: Share Gasolina URL

Provide your Gasolina API URL to LayerZero Labs:

```
https://your-gasolina-instance.com
```

### Step 2: DVN Contract Deployment

LayerZero will:

1. Query your `/signer-info` endpoint to retrieve signer addresses
2. Deploy DVN contracts on all supported chains with:
   * Your signer addresses registered
   * Agreed-upon quorum threshold
   * Essence wallet as initial `ADMIN_ROLE` holder
3. Provide you with the DVN contract addresses for each chain

```mermaid wrap theme={null}
sequenceDiagram
participant LZ as LayerZero
participant G as Your Gasolina
participant C as Chains

    LZ->>G: GET /signer-info
    G->>LZ: Signer addresses
    LZ->>C: Deploy DVN contracts
    C->>LZ: Contract addresses
    LZ->>You: DVN addresses for OApp config
```

### Step 3: OApp Configuration

OApps configure your DVN using the contract addresses:

```solidity wrap theme={null}
// Example UlnConfig for OApp
UlnConfig({
    confirmations: 15,
    requiredDVNCount: 2,
    optionalDVNCount: 0,
    optionalDVNThreshold: 0,
    requiredDVNs: [
        0xYourDVNContractAddress,  // Your Gasolina DVN
        0xOtherDVNAddress          // Another DVN
    ],
    optionalDVNs: []
})
```

***

## Advanced Configuration

### Extra Context Verification

Add custom verification logic by implementing an API endpoint:

```typescript wrap theme={null}
// Your custom verification API
app.post('/verify', async (req, res) => {
  const {sentEvent, from} = req.body;

  // Implement your verification rules
  const isValid = await verifyCustomRules(sentEvent, from);

  res.json({valid: isValid});
});
```

**API Input Schema:**

```typescript wrap theme={null}
{
  sentEvent: {
    lzMessageId: {
      pathwayId: {
        srcEid: number,    // Source endpoint ID
        dstEid: number,    // Destination endpoint ID
        sender: string,    // Sender OApp address
        receiver: string,  // Receiver OApp address
      },
      nonce: number,
    },
    guid: string,
    message: string,
    options: { /* ... */ },
    onChainEvent: {
      chainName: string,
      txHash: string,
      blockNumber: number,
    }
  },
  from: string  // Transaction initiator
}
```

Configure the URL in your infrastructure config:

```typescript wrap theme={null}
extraContextGasolinaUrl: 'https://your-api.com/verify';
```

### Multi-Signer Setup

For enhanced security and availability, deploy multiple Gasolina instances with different signers:

| Instance   | Endpoint                        | Signers      |
| ---------- | ------------------------------- | ------------ |
| Gasolina 1 | `https://gasolina1.example.com` | Signers A, B |
| Gasolina 2 | `https://gasolina2.example.com` | Signers C, D |
| Gasolina 3 | `https://gasolina3.example.com` | Signers E, F |

Essence requests signatures from all instances in parallel, then combines them for submission.

Configure quorum to require signatures from multiple instances (e.g., 4 of 6 signers across 3 instances).

***

## Managing Configuration Changes

As a Gasolina operator, you maintain full control over the DVN through the signer quorum.

### Change Quorum Threshold

```bash wrap theme={null}
ts-node scripts/configChangePayloads/createSetQuorumSignatures.ts \
    -e mainnet \
    -c ethereum,bsc,avalanche \
    --oldQuorum 2 \
    --newQuorum 3
```

### Add a Signer

```bash wrap theme={null}
ts-node scripts/configChangePayloads/createAddOrRemoveSignerSignatures.ts \
    -e mainnet \
    -c ethereum,bsc,avalanche \
    -q 2 \
    --signerAddress 0xNewSignerAddress \
    --shouldRevoke 0
```

### Remove a Signer

```bash wrap theme={null}
ts-node scripts/configChangePayloads/createAddOrRemoveSignerSignatures.ts \
    -e mainnet \
    -c ethereum,bsc,avalanche \
    -q 2 \
    --signerAddress 0xOldSignerAddress \
    --shouldRevoke 1
```

### Emergency Admin Takeover

The DVN contract includes a `quorumChangeAdmin` function that allows the signer quorum to reassign the admin role **without requiring the current admin's permission**. This ensures signers maintain ultimate control over the DVN even if the admin role has been delegated to a service like Essence.

#### ExecuteParam Structure

The function accepts a single `ExecuteParam` struct:

```solidity wrap theme={null}
struct ExecuteParam {
    uint32 vid;           // DVN instance identifier (endpoint v1 eid or v2 eid % 30000)
    address target;       // DVN contract address (must equal address(this))
    bytes callData;       // abi.encode(newAdminAddress)
    uint256 expiration;   // Unix timestamp (must be in the future)
    bytes signatures;     // Concatenated quorum signatures, sorted by signer address
}
```

#### Step-by-Step Implementation

**Step 1: Prepare the Parameters**

```javascript wrap theme={null}
const ethers = require('ethers');

// Configuration
const dvnAddress = '0xYourDVNContractAddress';
const newAdminAddress = '0xYourControlledAddress';
const vid = 101; // Your DVN's vid (check contract or use endpoint v1 eid)
const expiration = Math.floor(Date.now() / 1000) + 7 * 24 * 60 * 60; // 1 week from now

// Encode the new admin address as callData
const callData = ethers.utils.defaultAbiCoder.encode(['address'], [newAdminAddress]);
```

**Step 2: Generate the Hash for Signing**

```javascript wrap theme={null}
// Hash follows the DVN contract's hashCallData format
const hash = ethers.utils.keccak256(
  ethers.utils.solidityPack(
    ['uint32', 'address', 'uint256', 'bytes'],
    [vid, dvnAddress, expiration, callData],
  ),
);
```

**Step 3: Collect Quorum Signatures**

Each signer must sign the hash. Signatures must be sorted by signer address (ascending) before concatenation:

```javascript wrap theme={null}
// Each signer signs the hash
const signers = [signer1, signer2, signer3]; // Your Wallet instances
const signatures = [];

for (const signer of signers) {
  const sig = await signer.signMessage(ethers.utils.arrayify(hash));
  signatures.push({
    address: await signer.getAddress(),
    signature: sig,
  });
}

// Sort by address (required by contract)
signatures.sort((a, b) => a.address.toLowerCase().localeCompare(b.address.toLowerCase()));

// Concatenate signatures
const concatenatedSignatures = ethers.utils.solidityPack(
  signatures.map(() => 'bytes'),
  signatures.map((s) => s.signature),
);
```

**Step 4: Submit the Transaction**

```javascript wrap theme={null}
const dvnAbi = [
  'function quorumChangeAdmin((uint32 vid, address target, bytes callData, uint256 expiration, bytes signatures) _param) external',
];

const dvnContract = new ethers.Contract(dvnAddress, dvnAbi, provider);

// Anyone can submit this transaction - no special permissions required
const tx = await dvnContract.quorumChangeAdmin({
  vid: vid,
  target: dvnAddress,
  callData: callData,
  expiration: expiration,
  signatures: concatenatedSignatures,
});

await tx.wait();
console.log('Admin role transferred to:', newAdminAddress);
```

#### Validation Requirements

The contract validates:

| Check      | Requirement                                  |
| ---------- | -------------------------------------------- |
| Expiration | `expiration > block.timestamp`               |
| Target     | `target == address(this)` (the DVN contract) |
| VID        | `vid == contract.vid`                        |
| Signatures | Must meet quorum, sorted by signer address   |
| Replay     | Hash must not have been used before          |

<Warning>
  Before Taking Over Admin:

  * **Gas infrastructure**: Ensure you have gas management ready on all chains where you'll submit transactions
  * **Quorum coordination**: Collect signatures from enough signers to meet the quorum threshold
  * **Transaction systems**: Have reliable transaction submission infrastructure prepared
  * **Test first**: Test the process on testnet before executing on mainnet
</Warning>

<Tip>
  The `quorumChangeAdmin` function is defined in [DVN.sol](https://github.com/LayerZero-Labs/LayerZero-v2/blob/main/packages/layerzero-v2/evm/messagelib/contracts/uln/dvn/DVN.sol) lines 137-160.
</Tip>

***

## Operational Management

### Monitoring

<Tabs>
  <Tab title="AWS">
    * **CloudWatch Logs**: Automatic log collection
    * **CloudWatch Alarms**: Set up error rate monitoring
    * **SNS Notifications**: Configure alerts

    ```bash wrap theme={null}
    # Tail logs
    aws logs tail /ecs/gasolina-api --follow
    ```
  </Tab>

  <Tab title="GCP">
    * **Cloud Logging**: Automatic log collection
    * **Alerting Policies**: Configure error notifications
    * **Notification Channels**: Set up email/Slack alerts

    ```bash wrap theme={null}
    # View recent logs
    gcloud logging read "resource.type=cloud_run_revision" --limit 50
    ```
  </Tab>
</Tabs>

### Scaling

| Platform | Scaling Method                                 |
| -------- | ---------------------------------------------- |
| AWS      | ECS auto-scales based on CPU/memory thresholds |
| GCP      | Cloud Run auto-scales based on request volume  |

### Key Rotation

**KMS Keys (Recommended)**

* AWS KMS supports automatic key rotation
* Update DVN contract if key ID changes

**Mnemonic Keys**

1. Generate new mnemonic
2. Update Secrets Manager
3. Update wallet configuration
4. Redeploy application
5. Update DVN contract with new signer addresses

***

## Troubleshooting

### Common Issues

| Issue                                    | Solution                                               |
| ---------------------------------------- | ------------------------------------------------------ |
| "API has not been used in project" (GCP) | Wait a few minutes for API enablement to propagate     |
| "Resource already exists" (AWS)          | Delete `GasolinaMetricLogGroup` and S3 bucket, retry   |
| RPC connection failures                  | Verify endpoints, check API keys, add backup providers |
| Signature verification failures          | Ensure signer addresses match DVN contract config      |

### Debug Commands

```bash wrap theme={null}
# AWS: Check ECS logs
aws logs tail /ecs/gasolina-api --follow

# GCP: Check Cloud Run logs
gcloud logging read "resource.type=cloud_run_revision" --limit 50

# Test signing manually
curl -X POST https://your-instance.com \
    -H "Content-Type: application/json" \
    -d @test-payload.json
```

***

## Production hardening checklist

<Warning>
  The items below describe the production hardening posture every Gasolina-derived DVN deployment should meet. The reference deployment templates in [gasolina-aws](https://github.com/LayerZero-Labs/gasolina-aws) and [gasolina-gcp](https://github.com/LayerZero-Labs/gasolina-gcp) may not enable all of these by default; treat this checklist as the *required* posture for any DVN attesting production messages, regardless of the template defaults. Items marked `<verify default in templates>` require security-team confirmation of the current default state in the reference templates.
</Warning>

A Gasolina deployment that signs production attestations is part of the trust boundary of every OApp using your DVN. The checklist below is the minimum hardening posture before signing for mainnet messages.

### API Gateway / network perimeter

* [ ] **WAF enabled.** Rate limits, payload-size limits, common-injection rule sets attached. `<verify default in templates>`
* [ ] **IAM authentication required** on every endpoint that accepts signed-request inputs. No anonymous endpoints in production. `<verify default in templates>`
* [ ] **IP allowlist** restricts API Gateway access to the specific upstream callers you expect (LayerZero Endpoint workers, your own monitoring, integrators if applicable). `<verify default in templates>`
* [ ] **No public-binding** on the worker process itself. The signer process must be in a private VPC subnet, reachable only via the API Gateway / load balancer. `<verify default in templates>`
* [ ] **TLS 1.2+ enforced** end-to-end, including internal hops between API Gateway and worker.
* [ ] **mTLS** between API Gateway and worker if your threat model requires defense against a compromised internal-network attacker.
* [ ] **No introspection / health endpoints** that disclose the configured RPC providers, signer counts, or service identifiers to unauthenticated callers. `<verify default in templates>`

### RPC providers (`providers.json`)

The DVN's correctness depends entirely on what its RPCs tell it about the source chain. Treat RPC infrastructure as part of the trust boundary.

* [ ] **`quorum >= 2`** for every chain. A `quorum: 1` configuration means a single compromised RPC can feed forged source-chain data and the DVN will sign attestations of events that did not occur. `<verify default in templates>`
* [ ] **All configured RPCs treated as primary**, not as failover. Backup-only RPCs do not contribute to consensus and reduce the effective quorum.
* [ ] **At least 3 RPC providers** per chain for any production deployment. More for chains where your DVN is high-volume.
* [ ] **Provider diversity** — no two RPCs sharing infrastructure (e.g., not two endpoints from the same vendor's load balancer; not two self-hosted nodes on the same cloud).
* [ ] **Documented RPC selection rationale** — record why each RPC was chosen, when it was last reviewed, and the conditions under which it would be replaced.
* [ ] **Active drift monitoring** — alert on disagreement between RPCs at the same block. Disagreement that exceeds a baseline rate is an attack indicator.
* [ ] **Reorg-aware confirmation depth** — your DVN's `confirmations` value must exceed the source chain's typical reorg depth by a margin appropriate to the attestation value at stake.

### Configuration storage

* [ ] **Provider config (`providers.json`, signer-set, quorum settings) is hash-pinned and version-controlled.** Mutable storage (e.g., a writable S3 bucket without object lock or with broad write IAM) is a configuration-rotation attack surface. `<verify default in templates>`
* [ ] **Object Lock or equivalent immutability** on configuration object storage where supported.
* [ ] **Versioned access logs** on every read and write of configuration objects. Read access is a useful pre-attack signal; write access without a corresponding governance change is an exfiltration or pre-positioning indicator.
* [ ] **Config changes require a multi-party process** (e.g., PR + multi-sign approval + deployment). No single operator should be able to rotate `providers.json` to attacker-controlled endpoints unilaterally.

### Binary integrity

* [ ] **SHA256 attestation** on every binary deployed to a signer node. The attestation is verified before the binary runs.
* [ ] **Reproducible builds** of the DVN worker, with the build pipeline documented publicly.
* [ ] **Signed releases** — release artifacts published with cryptographic signatures from the build pipeline.
* [ ] **Supply-chain pinning** — package manifests pin to specific versions or hashes; CI fails on drift.
* [ ] **Runtime integrity check** (file-integrity monitoring on the running node) detects post-deployment binary swaps.

### Key management

* [ ] **HSM or cloud-KMS-backed signing keys** in production. No long-lived keys in plaintext on disk.
* [ ] **Documented rotation policy** — keys rotate on a defined cadence and on suspicion of compromise.
* [ ] **Multi-party signing** where supported (threshold signatures across operators reduces the impact of a single signer's key compromise).
* [ ] **Audit log on every signing operation**, retained for incident-response.

### Monitoring and detection

* [ ] **Per-pathway attestation latency** is tracked; alerts fire on attestations that are unusually fast (possible pre-positioning), unusually slow (possible degradation), or in non-canonical block ranges.
* [ ] **Source-chain ↔ destination-chain reconciliation** runs continuously; alerts fire on attestations that don't correspond to source-chain emit events.
* [ ] **Configuration drift detection** alerts on changes to `providers.json`, signer-set, or quorum settings.
* [ ] **Authentication-failure / authorization-failure rates** are alerted (probe activity is an attack precursor).
* [ ] **RPC divergence rate** alerted (see "RPC providers" above).
* [ ] **On-call rotation** receives alerts. A monitoring dashboard nobody is paged on is not a control.

### Incident response

* [ ] **Documented kill-switch** — how to stop the DVN from signing within minutes of detection. Tested in a non-production environment within the last quarter.
* [ ] **Isolation playbook** — how to remove a compromised RPC, signer, or node from the active set without taking the whole DVN offline.
* [ ] **Communication path** to integrators using your DVN, kept current.

## Security best practices (summary)

The production hardening checklist above supersedes the items below. The list is retained as a quick reference.

1. **Key Management**
   * Use HSM-backed keys (KMS) for production
   * Implement key rotation policies
   * Monitor key usage patterns

2. **Network Security**
   * Restrict API Gateway access (WAF, IAM auth, IP allowlist required for production)
   * Use VPC endpoints for internal communication
   * Do not bind the worker process to a public IP

3. **Monitoring**
   * Set up alerts for unusual signature request patterns
   * Monitor RPC provider response times and divergence
   * Track error rates and latency

4. **Backup and Recovery**
   * Backup configuration regularly
   * Document recovery procedures
   * Test disaster recovery plans periodically

***

## Repository Links

| Resource           | Link                                                                                                                               |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| AWS Infrastructure | [gasolina-aws](https://github.com/LayerZero-Labs/gasolina-aws)                                                                     |
| GCP Infrastructure | [gasolina-gcp](https://github.com/LayerZero-Labs/gasolina-gcp)                                                                     |
| DVN Contract       | [DVN.sol](https://github.com/LayerZero-Labs/LayerZero-v2/blob/main/packages/layerzero-v2/evm/messagelib/contracts/uln/dvn/DVN.sol) |

***

## Next Steps

* [Gasolina Overview](/v2/workers/off-chain/gasolina-overview) - Architecture and security model
* [DVN Technical Reference](/v2/workers/off-chain/dvn-technical-reference) - Contract methods and events
* [DVN Overview](/v2/workers/off-chain/dvn-overview) - General DVN concepts

<Info>
  For implementation support, reach out through [LayerZero Discord](https://discord.com/invite/ktbvm8Nkcr) or open an issue in the respective GitHub repository.
</Info>
