Skip to main content
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:

AWS Implementation

Step 1: Clone and Setup

Step 2: Configure AWS Authentication

Step 3: Choose Signer Type

You have two options for managing signing keys:

Step 4: Configure Infrastructure

Edit cdk/gasolina/config/index.ts:

Step 5: Configure RPC Providers

Edit cdk/gasolina/config/providers/mainnet/providers.json. Key each entry by chain name, list the independent provider entities under uris, and set quorum to how many must return matching responses:
  • Use at least 3 to 4 independent provider entities per chain for production quorum, not just failover; multiple URLs from a single vendor count as one fault domain
  • Prioritize reliable, independent providers (different vendors such as Alchemy, Infura, QuickNode, or an operator-run node)
  • Set quorum to the number of providers that must return matching responses (production: at least 3)

Step 6: Configure Wallet Definitions (Mnemonic Only)

This step applies only to the development and testing mnemonic flow. Production deployments use KMS (Step 3) and do not configure mnemonic wallet definitions.
If using mnemonics, edit cdk/gasolina/config/walletConfig/mainnet.json:

Step 7: Bootstrap CDK (First Time Only)

Step 8: Deploy Infrastructure

After successful deployment, you’ll see:

Step 9: Test Deployment

For production (mainnet), Gasolina must sit behind an authenticated gateway (IAM/SigV4, mTLS, or private networking) and status routes such as /signer-info and /provider-health must not be reachable by unauthenticated callers (see the production hardening checklist). Run these probes through your authenticated control plane, not against a public URL.
A successful response looks like:

Google Cloud Platform Implementation

Step 1: Clone and Setup

Step 2: Configure GCP Project

Step 3: Create Terraform Backend Storage

Step 4: Configure Terraform Backend

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

Step 5: Configure Infrastructure Variables

Edit terraform/lz-mainnet-verifier.tfvars:

Step 6: Configure RPC Providers

Edit terraform/providers-mainnet.json. Key each entry by chain name, list the independent provider entities under uris, and set quorum to how many must return matching responses:
  • Use at least 3 to 4 independent provider entities per chain for production quorum; multiple URLs from a single vendor count as one fault domain
  • Set quorum to the number of providers that must return matching responses (production: at least 3)

Step 7: Deploy with Terraform

Step 8: Test Deployment

For production (mainnet), the Cloud Run service must require authentication (deploy with --no-allow-unauthenticated and front it with an authenticated gateway or private ingress) so these probes run through the authenticated control plane rather than the public default Cloud Run URL, and status routes such as /signer-info and /provider-health are not anonymously reachable (see the production hardening checklist).

Integration with LayerZero

Once your Gasolina instance is deployed and tested:

Step 1: Share Gasolina URL

Provide your Gasolina API endpoint to LayerZero Labs. This must be the authenticated gateway endpoint (IAM/SigV4, mTLS, or private-network ingress), not a publicly open URL; coordinate the required caller credentials or role with LayerZero so requests are authenticated per the production hardening checklist:

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 signer threshold
    • Essence wallet as initial ADMIN_ROLE holder
  3. Provide you with the DVN contract addresses for each chain

Step 3: OApp Configuration

OApps configure your DVN using the contract addresses:

Advanced Configuration

Extra Context Verification

Extra-context verification is optional and owned by the Gasolina operator, who runs the verification endpoint and decides what it accepts or rejects. It runs in addition to Gasolina’s mandatory chain-derived checks, never instead of them — it can only make signing stricter, never looser. Enable it deliberately, and only with a policy whose intent the asset issuer / OApp has agreed to; a generic DVN should not impose app-specific signing decisions on its own (see Additional recommendations for OApp-owned DVNs). Add custom verification logic by implementing an API endpoint:
API Input Schema:
The endpoint must return a bare JSON boolean: true allows Gasolina to sign, and false refuses signing. Configure the URL in your infrastructure config:
Returning false refuses to sign. If Gasolina is configured as a required DVN for the pathway, the message cannot reach VERIFIABLE because the destination ULN waits for every required DVN stamp. It will not be committed or delivered until the message is signed, the OApp changes its ULN config, or the nonce is skipped or unblocked through the appropriate Endpoint action, such as skip, nilify, or burn, depending on state.A refused nonce keeps later messages on the same pathway from becoming executable, because delivery depends on preceding nonces being verified or skipped. Before enabling extra-context checks, define asset-issuer and ecosystem impact, who can change or disable the policy, and how refused messages are unblocked. Log and alert on policy-check failures.

Multi-Signer Setup

For enhanced security and availability, deploy multiple Gasolina instances with different signers: Essence requests signatures from all instances in parallel, then combines them for submission. Configure the signer threshold to require signatures from multiple instances (e.g., 4 of 6 signers across 3 instances).

Managing Configuration Changes

Operator control over DVN configuration is split into two steps: producing a quorum-signed change payload, then submitting that payload on-chain. The scripts below generate the ExecuteParam/calldata and signer quorum signatures for signer-threshold and signer-set changes. They do not execute the change, submit a transaction, or pay gas. After generation, the payload must be submitted before its expiration. For normal signer and threshold changes, submission goes through the DVN execute(ExecuteParam[]) path and must be sent by an account with the DVN admin role; today operators typically send the generated payload to LayerZero Labs for submission through Essence. The separate quorumChangeAdmin recovery path is different: any account can submit a valid quorum-signed admin-change payload, because the contract verifies the signatures rather than trusting the sender. The signer quorum retains ultimate control: via quorumChangeAdmin, it can reassign the admin role without the current admin’s cooperation. See Emergency Admin Takeover.

Change Signer Threshold

This procedure changes the on-chain DVN signer threshold, not the RPC provider quorum in providers.json. Never set the production signer threshold below 2. Lowering the threshold below 2 should happen only as a documented emergency risk exception, and all threshold changes should go through reviewed governance or operational procedures.

Add a Signer

Remove a Signer

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:

Step-by-Step Implementation

Step 1: Prepare the Parameters
Step 2: Generate the Hash for Signing
Step 3: Collect Quorum Signatures Each signer must sign the hash. Signatures must be sorted by signer address (ascending) before concatenation:
Step 4: Submit the Transaction

Validation Requirements

The contract validates:
Before Taking Over Admin:
  • Gas infrastructure: Ensure you have gas management ready on all chains where you’ll submit transactions
  • Signer-threshold coordination: Collect signatures from enough signers to meet the signer threshold
  • Transaction systems: Have reliable transaction submission infrastructure prepared
  • Test first: Test the process on testnet before executing on mainnet
The quorumChangeAdmin function is defined in DVN.sol lines 137-160.

Operational Management

Monitoring

  • CloudWatch Logs: Automatic log collection
  • CloudWatch Alarms: Set up error rate monitoring
  • SNS Notifications: Configure alerts

Scaling

Key Rotation

KMS Keys (Recommended)
  • AWS KMS supports automatic key rotation
  • Update DVN contract if key ID changes
Mnemonic Keys (development/testing only) Production signers use KMS/HSM and must not be operated as mnemonics; migrate any mnemonic signer to KMS before production use.
  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

Debug Commands


Production hardening checklist

Gasolina holds DVN signing authority, so its job is simple: produce a signature only after the operator has independently verified that the LayerZero message is real, the source transaction has enough confirmations for the pathway’s finality and reorg-risk requirements, the request is inside its validity window, and the signed payload is derived from trustworthy chain data. A hardened DVN should satisfy the controls in each checklist below before it signs traffic. The short version: diversify your clients, use non-extractable keys, require at least 2 independent signatures, isolate signers, authenticate callers, use independent RPC quorum, validate caller-supplied security context, instrument audit logs, alert on anomalies, and keep an incident runbook.
The items below describe the production hardening posture every Gasolina-derived DVN deployment should meet. The reference deployment templates in gasolina-aws and 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.

Signers and threshold

Gasolina can return signatures from the signer keys configured for the destination chain. The on-chain DVN signer threshold determines how many signatures are required before verification succeeds.
  • Multiple independent signer identities. Configure more than one signer identity, and each signer must use a distinct key.
  • Threshold >= 2 in production. Require at least 2 signatures for production. Do not lower the production threshold below 2 except as a documented emergency risk exception. A threshold of 2 or more reduces the impact of any single signer key compromise.
  • Signer isolation. Run signers in separate compute or trust domains rather than hosting multiple signer containers on a single machine.
  • Signer inventory. Maintain an inventory of the signer addresses and public keys the operator owns and expects GET /signer-info to return for each production pathway.
  • Reviewed signer-key changes. Keep Gasolina signer-key changes behind reviewed deployment and key-management procedures.
  • Reviewed threshold changes. Keep on-chain DVN signer threshold changes behind reviewed governance or operational procedures.
  • Documented rotation policy. Keys rotate on a defined cadence and on suspicion of compromise.

Managed keys vs mnemonics

Never use mnemonics. They are extractable secrets: anyone who can read the secret, dump process memory, or capture a deployment artifact can reuse the key outside Gasolina. Prefer managed signing services.
The mnemonic-based signer option shown earlier in this guide (Step 3: Choose Signer Type) is intended for local development and testing only. Production deployments must use cloud KMS or HSM-backed keys.
  • Use cloud KMS or HSM-backed keys for production signers. No long-lived keys in plaintext on disk.
  • Grant routine signing permission only to the expected Gasolina runtime identity.
  • Define any human, CI, or admin signing access as time-bound break-glass access with documented approval, immutable logs, and appropriate alerts.
  • Keep KMS/HSM policy changes behind reviewed change control.
Gasolina (TypeScript) supports AWS KMS and GCP Cloud KMS for HSM-backed signing. The KMS signer is selected through environment variables on the running service:
  • SIGNER_TYPE=KMS
  • KMS_CLOUD_TYPE=AWS or KMS_CLOUD_TYPE=GCP
  • LAYERZERO_KMS_IDS: comma-separated list of KMS key IDs, one per signer key
  • For GCP Cloud KMS: GCP_PROJECT_ID and GCP_KEY_RING_ID
In the AWS CDK deployment these are derived from the signerType: 'KMS' and kmsNumOfSigners settings (see Step 3: Choose Signer Type above); the GCP Terraform deployment sets them on the Cloud Run service. Operators using Azure Key Vault, another HSM, or a custom signer should provide an equivalent non-extractable signer adapter and apply the same permission, monitoring, and alerting requirements.

Access control and audit trail

Gasolina should be reachable only through an authenticated control plane. It does not sign arbitrary payloads: it reconstructs the message from chain data and runs validation before signing. The risk of public exposure is that attackers can directly exercise the signing workflow, abuse expensive RPC-backed validation paths, probe validation edge cases, and turn any caller-context or validation bug into a signing or availability incident.
  • Authenticated gateway. Put Gasolina behind IAM/SigV4, mTLS, VPN, private networking, or an equivalent authenticated gateway. No anonymous endpoints in production. <verify default in templates>
  • No public exposure. Do not expose the Gasolina task, container, or internal load balancer directly to the public internet. The signer process must sit in a private subnet, reachable only via the gateway or load balancer. <verify default in templates>
  • Restrict signing-route access to the expected caller role or service, not a broad account or network range. <verify default in templates>
  • Rate-limit signing and status routes (such as GET /signer-info and GET /provider-health) per caller at the gateway or equivalent network control where supported. Attach payload-size limits and common-injection rule sets where a WAF is available. <verify default in templates>
  • TLS 1.2+ enforced end-to-end, including internal hops between the gateway and worker.
  • No introspection or health endpoints that disclose the configured RPC providers, signer counts, or service identifiers to unauthenticated callers. <verify default in templates>
  • Instrument audit logs. Add application, gateway, or sidecar instrumentation to log caller identity, source transaction hash, LayerZero message ID, source/destination chain, dvnAddress, signer addresses, outcome, and rejection reason.
  • Retain audit logs long enough to investigate delayed reports of fraudulent or anomalous signatures.

Client and deployment diversity

Client diversity reduces common-mode risk from implementation bugs, compromised dependencies, or compromised deployment infrastructure.
  • Run more than one independent Gasolina deployment when possible.
  • Make deployments independent. Make deployments independent across release pipelines, deploy credentials, runtime credentials, hosts, and registries or image digests.
  • Add independent implementations when available, such as Rust or partner-written clients.
  • Expose resolved payloads, signer addresses, and signature results from each deployment so downstream policy can compare them for high-value pathways.
  • Pin production images by immutable digest where possible and require reviewed deploys.
Supply-chain and binary integrity controls support deployment diversity. Where supported, pin package manifests to specific versions or hashes and fail CI on drift, use reproducible builds with a publicly documented build pipeline, publish release artifacts with cryptographic signatures from the build pipeline, verify a SHA256 attestation before each signer binary runs, and use file-integrity monitoring on the running node to detect post-deployment binary swaps.

RPC quorum and provider configuration

A compromised or faulty RPC provider can lie about receipts, blocks, timestamps, contract state, or transaction contents. Quorum only helps if the providers and quorum strategy are independent and protected from tampering. This RPC provider quorum (how many independent providers must agree on source-chain data) is a separate control from the on-chain signer threshold in Signers and threshold: the quorum governs the data Gasolina reads, while the threshold governs how many signatures the DVN requires.
Security-critical data includes:
  • source transaction receipts and emitted packet events,
  • message hash inputs reconstructed from source-chain state,
  • source block confirmations,
  • destination block timestamps used for expiration checks,
  • destination ULN/DVN config and verification state,
  • read-message time markers and resolved read payload inputs.
  • Use RPC quorum, not a single provider, for security-critical reads.
  • Require matching responses from at least 3 or 4 independent provider entities for every chain in production. Multiple URLs from one vendor count as one fault domain. A single compromised or faulty RPC can otherwise feed forged source-chain data and the DVN will sign attestations of events that did not occur, so a single-provider (quorum: 1) configuration is never acceptable. <verify default in templates>
  • Treat provider entities as separate fault domains, for example operator-run nodes, dedicated external providers, and shared third-party providers.
  • Treat all configured RPCs as primary, not as failover. Backup-only RPCs do not contribute to consensus and reduce the effective quorum.
  • Prefer including an operator-run node in quorum, especially for high-value pathways.
  • Fail closed when quorum (at least 3 independent providers) cannot be reached or providers disagree on security-critical data.
  • Use 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.
  • Export RPC health, block lag, latency, disagreement rate, and quorum-failure metrics.
  • Document RPC selection rationale. Record why each RPC was chosen, when it was last reviewed, and the conditions under which it would be replaced.
  • Restrict writes to provider lists and quorum strategy files to the deploy pipeline or another reviewed change path. Configuration changes should require a multi-party process so no single operator can rotate provider endpoints unilaterally.
  • Enable versioning or audit trails for provider configuration. Where supported, store configuration on immutable object storage (for example, Object Lock) and keep versioned access logs on every read and write. <verify default in templates>
  • Do not put RPC API keys or credentials in logs or public config.

Required checks before every signature

Gasolina reconstructs the source message from chain state and should not trust caller-provided data by itself. If caller-provided identifiers, hashes, or security context do not match the chain-derived data and configured pathway requirements, Gasolina should reject the request instead of signing a payload built from different verified data.
The checks below are what every Gasolina client is expected to perform before signing. Operators should verify that each deployed client performs these checks and that operator-controlled settings, such as supported chains, RPC/quorum configuration, and enabled extra policy checks, are configured as intended.
Every signature must pass all of the following checks:
  • Supported chains: source and destination chains are supported.
  • Valid protocol type: protocol type is valid for the request (MESSAGE or READ) and matches the requested ULN/version.
  • Source transaction exists on the source chain.
  • Packet event matches: packet event exists and matches the requested message ID, pathway, nonce, and version.
  • Message hash matches packet data reconstructed from source-chain state.
  • Block confirmations (message verification): for message verification, the source transaction has at least the caller-supplied blockConfirmation.
  • Time markers (Read verification): for Read verification, resolved time markers are valid and their referenced blocks have the required confirmations.
  • Expiration window valid: request expiration is still valid and is not more than the configured maximum window in the future.
  • Destination config read via RPC stack: destination ULN/DVN config and current verification state are read through the configured RPC stack. Production deployments should configure that stack for quorum as described above.
  • Payload built only from verified state: final hash call data and resolved payload are built only from verified source-chain and destination-chain state.
Only after all required client checks and enabled extra policy checks pass should signer keys produce signatures.
  • Client consistency. Verify every Gasolina client, deployment, or implementation whose signatures may be accepted implements these checks and uses the intended supported-chain, RPC/quorum, and extra-policy configuration.

Additional recommendations for OApp-owned DVNs

OApp-owned or app-specific DVNs may have enough application context to apply business, risk, or compliance checks beyond the base protocol checks. Generic DVNs are usually blind to application semantics and should not make app-specific signing decisions unless the OApp owner has explicitly provided the required payload context, policy, and authority. Before an OApp-owned or app-specific DVN enables these checks, define:
  • Implementation: where the check runs, for example a Gasolina extra-context endpoint, sidecar, upstream verifier/orchestrator, or independent client-comparison service.
  • OApp-owner policy: which apps, pathways, payloads, or message types the DVN is expected to sign or refuse.
  • Asset-issuer impact: whether refusing to sign can affect minting, burning, unlocking, withdrawals, or other asset movement.
  • Ecosystem impact: whether refusals can affect pathway liveness, ordered nonce progress, composability, or downstream user experience.
  • Business and ecosystem alignment: whether the policy changes the relationship between the DVN, the OApp owner, asset issuers, or other ecosystem participants.
  • Operational process: who can change or disable the policy, how emergency exceptions work, how refused messages can resume or be unblocked, and how refusals are communicated.
Generic DVNs should treat the examples below as application-owner responsibilities unless they have a specific integration that gives them reliable decoding, expected payload semantics, and an agreed policy.
Examples for OApp-owned or app-specific DVNs include:
  • Inflow/outflow controls for applications where the OApp owner understands the message format and asset semantics well enough to make the check reliable.
  • Emergency controls that allow the operator to intentionally fail closed for a compromised pathway, chain, RPC provider, or app.
Consider allowlists for approved pathways, apps, message types, token routes, or specific payloads, only when this restriction is defined by the OApp owner, and its ecosystem impact is understood.
Policy-check failures should be logged and alerted. OApp owners and DVN operators should understand that refusing to sign a nonce can block later ordered messages on the same pathway until the OApp or protocol operators take corrective action.

Monitoring and alerts

Gasolina clients do not emit structured success-path signing audit logs for all of the fields below. Operators should add application, gateway, or sidecar instrumentation before treating these as covered controls.
  • Alert on unexpected signer address changes or public-key changes.
  • Alert on KMS/HSM key-policy, grant, or permission changes on signing keys.
  • Alert on KMS/HSM signing attempts from unexpected principals or infrastructure.
  • Alert on abnormal signing volume by caller, pathway, destination chain, or signer key.
  • Track per-pathway attestation latency, alerting on attestations that are unusually fast (possible pre-positioning), unusually slow (possible degradation), or in non-canonical block ranges.
  • Alert on duplicate-sign attempts and repeated requests missing dvnAddress.
  • Alert on RPC quorum failures, provider disagreement, provider lag, and provider-config changes.
  • Alert when extra policy checks reject unusually often or stop responding.
  • Alert when health-check or status routes (such as GET /signer-info and GET /provider-health) are called at unusual volume.
  • Alert on authentication-failure and authorization-failure rates. Probe activity is an attack precursor.
  • Run continuous source-chain to destination-chain reconciliation, alerting on attestations that do not correspond to source-chain emit events.
  • Ensure alerts route to a staffed on-call channel or paging system. A monitoring dashboard nobody is paged on is not a control.
  • Keep a runbook for key compromise, signer rotation, bad RPC/provider data, provider-config tampering, deploy rollback, and emergency pathway disablement. Include a kill-switch to stop signing within minutes, tested in a non-production environment at least quarterly; an isolation playbook to remove a compromised RPC, signer, or node without taking the whole DVN offline; and a current communication path to integrators using your DVN.


Next Steps

For implementation support, reach out through LayerZero Discord or open an issue in the respective GitHub repository.